The Data Structure¶
One of the main aims of uniplot is to separate plot data from it’s representation. As such a plot data structure has been defined, which will be described on this page.
The data structure is split into three main data structures (that will eventually make sense I promise):
- Graph
The
graphis the “top-level” data structure and contains the plots as well as some other meta information (such as the style to be used). There may only be onegraphper file.The
graphroughly corresponds to matplotlib’sfigureclass.- Plot
A
plotis a set of axes including the data plotted on those axes and any labels or annotations.A
plotis similar to matplotlib’ssubplot.- Axes
axescontain the actual data to be plotted on theplotas well as legend titles for the data.The
axesare equivalent to matplotlib’saxesclass.
From here on I will go into more depth on each of these data structures. Since Hip is the unofficial “official” file format of uniplot I will be giving examples in a Hip-like format but in the interest of inclusion I will also be rewriting the examples in JSON.
Note
Many strings can be given LaTeX style maths which will be typeset according
to the instructions given by
matplotlib. This largely applies to titles, labels and
legends.
Graph¶
The graph is the top-level data structure. There can only be one graph per file (which can be implied as we will see later) and each graph produces one file when processed.
The attributes allowed in the graph are as follows (title, style and
share are optional and default to an empty string, the standard style and
yes respectively).
title: <string>
style: <string>
share: <bool>
plots: <list: <object> | object>
title: "The Title of the Graph"
style: "ggplot2"
share: no
plots: ...
{
"title": "The Title of the Graph",
"style": "ggplot2",
"share": false,
"plots": {}
}
title- This string will be placed centrally at the top of the graph. There is no
default title. Titles may be given LaTeX style maths surrounded by
$. style- The graph will have this stylesheet applied to it if it can be found. If it is not specified (or the specified one can not be found) then the standard matplotlib style will be used.
share- If the graph consists of multiple plots the values on the axes can be shared between the plots to make the graph less cluttered. This is on by default.
plots- A list of plot objects or a single plot object. See Plots.
Plots¶
A plot sits within a graph. There can be as many plots as matplotlib can handle (as far as I’m aware there is no specific cap on this) and all plots will be placed on the graph in a roughly square shape.
The following attributes are allowed (title and labels are optional).
title: <string>
labels:
x: <string>
y: <string>
axes: <list: <object> | object>
title: "The Title of This Particular Plot"
labels:
x: "The x-axis"
y: "The y-axis"
axes: ...
{
"title": "The Title of This Particular Plot",
"labels": {
"x": "The x-axis",
"y": "The y-axis"
},
"axes": {}
}
title- This string will be placed centrally above the plot. There is no default
title. Titles may be given LaTeX style maths surrounded by
$. labels- These are the axis labels which will be placed next to the corresponding
axis. These default to
"x"and"y"and may be supplied LaTeX style maths.
Todo
Allow a single axes object as well as a list.
axes- A list of axes objects. See Axes.
Axes¶
The axes contain the things which directly relate to each set of data. This is easily the most complex part of the uniplot data structure since the data can be specified in many ways.
In the first code-block below x and y have been specified twice to show
the composition of the object format. In the second and third blocks an array of
axes has been shown, to show the many ways of specifying an axis.
legend: <string>
x: <list: <number> | string>
x:
values: <list: <number> | string>
errors: <number | list: <number> | string>
y: <list: <number> | string>
y:
values: <list: <number> | string>
errors: <number | list: <number> | string>
-
# 1
legend: "A straight line."
x: 0, 1, 2, 3, 4
y: 0, 2, 4, 6, 8
--
# 2
legend: "A quadratic."
x:
values: 0, 1, 2, 3
y:
values: 0, 1, 4, 9
--
# 3
legend: "Noisy data."
x:
values: 1e6, 2e6, 3e6, 4e6, 5e6, 7e6
errors: 0.01
y:
values: 2e-3, 4e-3, 5e-3, 9e-3, 8e-3, 12e-3
errors: 1e-3, 1e-3, 1e-3, 2e-3, 3e-3, 1e-3
--
# 4
legend: "Values obtained from a csv."
x: "path/to/file.csv:0"
y: "path/to/file.csv:1"
--
# 5
legend: "Values obtained from a whitespace delimited file."
x:
values: "path/to/a/file.ext:0:1"
errors: "path/to/a/file.ext:2:1"
y:
values: "path/to/a/file.ext:1:1"
errors: "path/to/a/file.ext:3:1"
--
# 6
x:
values: 1, 2, 8, 5, 3, 5
errors: "path/to/this/file.csv:0:2"
y:
values: "path/to/that/file.dat:4"
errors: 0.3
-
[
{
"legend": "A straight line.",
"x": [0, 1, 2, 3, 4],
"y": [0, 2, 4, 6, 8]
},
{
"legend": "A quadratic.",
"x": {"values": [0, 1, 2, 3]},
"y": {"values": [0, 1, 4, 9]}
},
{
"legend": "Noisy data.",
"x": {
"values": [1000000, 2000000, 3000000, 4000000, 5000000, 7000000],
"errors": 0.01
},
"y": {
"values": [0.002, 0.004, 0.005, 0.009, 0.008, 0.012],
"errors": [0.001, 0.001, 0.001, 0.002, 0.003, 0.001]
}
},
{
"legend": "Values obtained from a csv.",
"x": "path/to/file.csv:0",
"y": "path/to/file.csv:1"
},
{
"legend": "Values obtained from a whitespace delimited file.",
"x": {
"values": "path/to/a/file.ext:0:1",
"errors": "path/to/a/file.ext:2:1"
},
"y": {
"values": "path/to/a/file.ext:1:1",
"errors": "path/to/a/file.ext:3:1"
}
},
{
"x": {
"values": [1, 2, 8, 5, 3, 5],
"errors": "path/to/this/file.csv:0:2"
},
"y": {
"values": "path/to/that/file.dat:4",
"errors": 0.3
}
}
]
legend- The
legendattribute gives the string to be used in the legend for that plot. If noaxeshas alegendattribute then the plot will not have a legend. There is no default legend label and LaTeX style maths can be used with legends. xandyThese contain the data to be plotted. If there is an
errorssupplied then an errorbar graph will be plotted, else a line graph will be plotted.The
axesin the Hip example are numbered using comments, eachaxesinstance will be explained in the following list (matching the numbers).- This
axesspecifies both the x- and y-axis as a simple list of numbers. This will plot a line graph. - This
axesonly uses avaluesattribute and plots a line graph. This works but is entirely redundant. - This
axesusesvaluesanderrorsand therefore plots an errorbar graph. The x-axis giveserrorsas a single number, this number is considered a percentage error and is multiplied by each number invaluesto give the absolute error on that number. The y-axis is given as a list of numbers, these numbers are considered absolute errors.errorsmust either be a single number or it must be the same length asvalues. - This
axesuses data from a CSV file (see Storing Data in a File). The x-values are stored in the 0th column and the y-values are stored in the 1st column. These files do not have to be the same and do not need to be in consecutive columns. - This
axesstores bothvaluesanderrorsin a whitespace delimited file. The columns are in the orderx-val|y-val|x-err|y-errand one row must be skipped from each column. - This
axesshows that all the previous examples can be mixed and matched to your liking.
- This
Storing Data in a File¶
Todo
Allow data to be read from other filetypes such as .xls files and maybe
even database files.
uniplot allows you to store values and errors in a file, this is useful
if you have a large amount of data which would be annoying and error prone to
write by hand. Currently only CSV and whitespaces delimited files are supported,
any file which does not have the extension .csv is assumed to be a
whitespace delimited file.
To do this you must provide in the following format:
"<path to file>:<zero-indexed column number>:<number of rows to skip>"
The path to the file can be either be relative to the directory from which the
program is run or it can be absolute. The zero-indexed column number is...
well... the column number of the data, zero-indexed. The number of rows to skip
is passed directly on to the skiprows argument of numpy.loadtxt and is
very useful if your file has header rows. The number of rows to skip does not
need to be specified and defaults to 0.
Omitting Structures¶
You don’t have to specify the graph in every file you write, since all
attributes (with the exception of plots) in a graph are optional you can
omit them entirely. This mean you can turn the following:
plots:
title: "Some title"
labels:
x: "x axis"
y: "y axis"
axes: ...
into this:
title: "Some title"
label:
x: "x axis"
y: "y axis"
axes: ...
Further still, all attributes of a plot are optional as well so you can omit this too. So the following:
plots:
axes:
legend: "Legendary legend entry"
x: 0, 1, 2, 3, 4
y: 0, 2, 4, 6, 8
becomes:
legend: "Legendary legend entry"
x: 0, 1, 2, 3, 4
y: 0, 2, 4, 6, 8
See examples for more in-depth examples.