templates
– Things that can be put in the report
This module contains classes that are supposed to act as containers of all
the information that is necessary to represent a test in a given format. For
instance, in the case of tables this includes the column contents, the headers,
etc. It does not include any formatting information, such as column
widths, floating-point precision, colours, etc. Decisions about the formatting
are handled by suitable formatting classes, such as Rst
.
- class valjean.javert.templates.TableTemplate(*columns, headers=None, units=None, highlights=None)[source]
A container class that encapsulates all the necessary information to represent a table.
Examples of use of mainly show in context of concatentation of
TableTemplate
, obtained with thejoin
method.>>> import numpy as np >>> tit1 = TableTemplate(np.float_(1.5), np.float_(1.4), ... headers=['egg', 'spam']) >>> tit2 = TableTemplate(np.float_(1.2), np.float_(0.9), ... headers=['egg', 'spam']) >>> stab12 = join(tit1, tit2) >>> print(len(tit1.columns), len(tit2.columns)) 2 2 >>> print(tit1.columns[0].size, tit2.columns[0].size) 1 1 >>> print(len(stab12.columns)) 2 >>> print(stab12.columns[0].size) 2 >>> print(f"{stab12!r}") class: <class 'valjean.javert.templates.TableTemplate'> headers: ['egg', 'spam'] egg: [1.5 1.2] spam: [1.4 0.9] highlights: [array([0., 0.]), array([0., 0.])]
stab12
contained bothtit1
andtit2
as expected. Headers of the columns are the same, length of the columns is the sum of the two.>>> tit3 = TableTemplate(np.float_(0.8), np.float_(1.1), ... headers=['knight', 'parrot']) >>> stab13 = join(tit1, tit3) Traceback (most recent call last): ... ValueError: TableTemplates to add should have same headers
An error is raised as the two
TableTemplate
don’t contain the same headers, so not the same kind of columns, thus they cannot be concatenated.It is also possible to join tables with same headers but different ‘types’ (scalars and arrays):
>>> tit4 = TableTemplate(np.arange(4), np.arange(4)*0.5, ... headers=['egg', 'spam']) >>> print(len(tit4.columns), tit4.columns[0].size) 2 4 >>> stab14 = join(tit1, tit4) >>> print(len(stab14.columns), stab14.columns[0].size) 2 5 >>> stab14.columns[0].size == tit1.columns[0].size + tit4.columns[0].size True >>> print(f"{stab14!r}") class: <class 'valjean.javert.templates.TableTemplate'> headers: ['egg', 'spam'] egg: [1.5 0. 1. 2. 3. ] spam: [1.4 0. 0.5 1. 1.5] highlights: [array([0., 0., 0., 0., 0.]), array([0., 0., 0., 0., 0.])]
It is also possible to join arrays, a bigger array is obtained, without separation between the initial
TableTemplate
:>>> tit5 = TableTemplate(np.arange(3)*0.1, np.arange(3)*0.05, ... headers=['egg', 'spam']) >>> stab45 = join(tit4, tit5) >>> print(len(stab45.columns), len(stab45.columns[0])) 2 7 >>> print(f"{stab45!r}") class: <class 'valjean.javert.templates.TableTemplate'> headers: ['egg', 'spam'] egg: [0. 1. 2. 3. 0. 0.1 0.2] spam: [0. 0.5 1. 1.5 0. 0.05 0.1 ] highlights: [array([0., 0., 0., 0., 0., 0., 0.]), array([0., 0., 0., 0., 0., 0., 0.])]
Any number of
TableTemplate
can be joined (if fulfilling the requirements).>>> stab145 = join(tit1, tit4, tit5) >>> print(f"{stab145!r}") class: <class 'valjean.javert.templates.TableTemplate'> headers: ['egg', 'spam'] egg: [1.5 0. 1. 2. 3. 0. 0.1 0.2] spam: [1.4 0. 0.5 1. 1.5 0. 0.05 0.1 ] highlights: [array([0., 0., 0., 0., 0., 0., 0., 0.]), array([0., 0., 0., 0., 0., 0., 0., 0.])]
The
TableTemplate.join
method updates the leftTableTemplate
as expected:>>> tit1.join(tit4, tit5) >>> print(f"{tit1!r}") class: <class 'valjean.javert.templates.TableTemplate'> headers: ['egg', 'spam'] egg: [1.5 0. 1. 2. 3. 0. 0.1 0.2] spam: [1.4 0. 0.5 1. 1.5 0. 0.05 0.1 ] highlights: [array([0., 0., 0., 0., 0., 0., 0., 0.]), array([0., 0., 0., 0., 0., 0., 0., 0.])]
- __init__(*columns, headers=None, units=None, highlights=None)[source]
Construct a table from a set of columns. The columns must be
numpy.ndarray
objects, and they must all contain the same number of elements (same array size).Column headers may be specified using the headers argument; in this case, the number of headers must be equal to the number of columns.
Column units can also be specified using the units argument. Again, you must pass as many units as there are columns.
Finally, it is possible to specify which table elements should be highlighted. This is done by passing a list of lists (or
numpy.ndarray
) to the highlights argument. Each element of the highlights (outer) list represents a table column and therefore must have the same shape as all the other columns; also, the length of highlights must be equal to the number of columns. Elements of the inner lists (ornumpy.ndarray
) must be booleans and indicate whether the corresponding table element must be highlighted.
- copy()[source]
Copy a
TableTemplate
object.- Return type:
Note
the highlignt function is not really copied, it has the same address as the self one. I don’t know how to change that.
- join(*others)[source]
Join a given number a
TableTemplate
to the current one.Only
TableTemplate
with the same number of columns and same headers can be joined. The method returns the updated current one.- Parameters:
others (list(TableTemplate)) – list of TableTemplates to be joined to the current TableTemplate
- __getitem__(index)[source]
Build a sliced
TableTemplate
from the currentTableTemplate
.Slicing is done like in the usual NumPy arrays, see: numpy indexing for more informations. No treatment like in
dataset
is done.
- data()[source]
Yield bytes representing self. Two
TableTemplate
objects containing equal data yield the same data.
- __eq__(other)[source]
Test for equality of self and another
TableTemplate
.
- __ne__(other)[source]
Test for inequality of self and another
TableTemplate
.
- __hash__ = None
- class valjean.javert.templates.CurveElements(values, bins, legend, *, index=0, errors=None)[source]
Define the characteristics of a curve to plot.
- __init__(values, bins, legend, *, index=0, errors=None)[source]
Construction of
CurveElements
: curve details (values, bins, etc).Values and errors (if given) should be
numpy.ndarray
of same shape (they must have only non-trivial dimension).Bins are stored as a list of
numpy.ndarray
. This list should have the same length as the dimension of the values.The index is used to share the plotting style between curves that should. For example, if on a plot there are the reference and two curves representing different data, let’s say ‘egg’ and ‘spam’, if we also want to draw the ratio of these data with the reference, the same style will be applied to ‘egg vs reference’ and ‘egg’ and to ‘spam vs reference’ and ‘spam’. In that case to ensure the same style ‘egg vs reference’ and ‘egg’ should have the same index (same for the ‘spam’ case).
- Parameters:
values (numpy.ndarray) – array to be represented on the plot, mandatory
bins (list(numpy.ndarray)) – bins to be used to represent the values
legend (str) – string to be used in the legend to characterize the curve, mandatory
index (int) – index of the curve (used for style for example)
errors (numpy.ndarray) – errors associated to values (per default only on 1D plots and y-axis)
- copy()[source]
Copy a
CurveElements
object.- Return type:
- __repr__()[source]
Printing of
CurveElements
.
- __str__()[source]
Printing of
CurveElements
.
- data()[source]
Generator yielding objects supporting the buffer protocol that (as a whole) represent a serialized version of self.
- __eq__(other)[source]
Test for equality of self and another
CurveElements
.
- __ne__(other)[source]
Test for inequality of self and another
CurveElements
.
- __hash__ = None
- class valjean.javert.templates.SubPlotAttributes(dim)[source]
Container to store sub-plots attributes:
axis limits
axis scale: linear (default) or logatithmic
additional horizontal or vertical lines
Theses attributes are independent of the used backend (examples: matplotlib, Root, gnuplot, D3). The backend then gets the attributes and apply them with its own features.
- __init__(dim)[source]
Initialisation of PlotAttributes.
The attributes of the instance are private.
- Parameters:
dim (int) – dimension of the data on the sub-plot (used to check consistency of limits)
- copy()[source]
Copy a
SubPlotAttributes
object.- Return type:
- property limits
Return limits.
- property lines
Return lines to be plotted.
- exception valjean.javert.templates.SubPlotElementsException[source]
Error raised if the sub plot looks inconsistent.
- class valjean.javert.templates.SubPlotElements(*, curves, axnames=('', ''), ptype='1D')[source]
Container to store a given sub-plot.
- __init__(*, curves, axnames=('', ''), ptype='1D')[source]
Initialisation of
SubPlotElements
.A subplot is defined as data (
curves
) sharing the same plotting properties:axis names
type of the plot (e.g.
'1D'
,'2D'
, …), see the chosen backend to get the list of possibilities (example:MplPlot
)axis scales
axis limits
The last axis name corresponds to the quantity to be drawn, the first ones to the bins.
Axis scales can be linear (default) or logarithmic (if set to
True
).Vertical or horizontal lines can also be added.
- Parameters:
curves (list(CurveElements)) – list of curves to go on the sub-plot
axnames (tuple) – name of the axes of the sub-plot
type (str) – type of the sub-plot, default:
'1D'
- copy()[source]
Copy a
SubPlotElements
object.- Return type:
- __repr__()[source]
Printing of
SubPlotElements
- __str__()[source]
Printing of
SubPlotElements
- data()[source]
Generator yielding objects supporting the buffer protocol that (as a whole) represent a serialized version of self.
- __eq__(other)[source]
Test of equality of self and another
SubPlotElements
.
- __ne__(other)[source]
Test for inequality of self and another
SubPlotElements
.
- __hash__ = None
- class valjean.javert.templates.PlotTemplate(*, subplots, small_subplots=True, suppress_xaxes=False, suppress_legends=False, backend_kw=None)[source]
A container for full test result to be represented as a plot. This includes all the datasets and the test result. This can also include p-values or other test parameters, depending on what is given to the
PlotTemplate
.Examples mainly present the
join
method, used to concatentatePlotTemplate
.>>> bins1, d11, d12 = np.arange(4), np.arange(4), np.arange(4)*10 >>> d13 = d11 + d12 >>> bins2, d2 = np.arange(5), np.arange(5)*0.5 >>> pit1 = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(d11, [bins1], 'd11', index=0)], ... axnames=['egg', 'brandy'])]) >>> pit2 = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(d12, bins=[bins1], legend='d12', index=1)], ... axnames=['egg', 'beer'])]) >>> pit3 = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(d13, legend='d13', bins=[bins1], index=2)], ... axnames=['egg', 'wine'])]) >>> splt123 = join(pit1, pit2, pit3) >>> print(f"{splt123!r}") class: <class 'valjean.javert.templates.PlotTemplate'> N subplots: 3 Subplot 0 axnames: ['egg', 'brandy'], plot type: 1D, N curves: 1 Curve 0 legend: d11 index: 0 bins: [array([0, 1, 2, 3])] values: [0 1 2 3] errors: None Subplot 1 axnames: ['egg', 'beer'], plot type: 1D, N curves: 1 Curve 0 legend: d12 index: 1 bins: [array([0, 1, 2, 3])] values: [ 0 10 20 30] errors: None Subplot 2 axnames: ['egg', 'wine'], plot type: 1D, N curves: 1 Curve 0 legend: d13 index: 2 bins: [array([0, 1, 2, 3])] values: [ 0 11 22 33] errors: None
As expected a new
PlotTemplate
is obtained, containing three subplots, each one containing one curve.Like in the TableTemplate case, the
PlotTemplate.join
method updates the leftPlotTemplate
as expected:>>> pit1.join(pit2, pit3) >>> pit1 == splt123 True
A new curve with the same axes will also create a new suplot:
>>> d14 = d11*2 >>> pit4 = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(d14, legend='d14', index=3, bins=[bins1])], ... axnames=['egg', 'beer'])]) >>> split24 = join(pit2, pit4) >>> print(split24) class: <class 'valjean.javert.templates.PlotTemplate'> Subplot 0 axnames: ['egg', 'beer'], plot type: 1D Curve 0 legend: d12 index: 1 bins: [array([0, 1, 2, 3])] Subplot 1 axnames: ['egg', 'beer'], plot type: 1D Curve 0 legend: d14 index: 3 bins: [array([0, 1, 2, 3])]
To get it in the same subplot it has to be done at creation.
>>> pit24 = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(d12, legend='d12', index=1, bins=[bins1]), ... CurveElements(d14, legend='d14', index=3, bins=[bins1])], ... axnames=['egg', 'beer'])]) >>> print(pit24) class: <class 'valjean.javert.templates.PlotTemplate'> Subplot 0 axnames: ['egg', 'beer'], plot type: 1D Curve 0 legend: d12 index: 1 bins: [array([0, 1, 2, 3])] Curve 1 legend: d14 index: 3 bins: [array([0, 1, 2, 3])] >>> split24 == pit24 False
N-dimensional plot templates can be built, but the plotting engine may not be able to convert multi-dimensional templates into plots.
The same behavior is expected for multi-dimensions plots:
join
will had a new subplot. To be noted: only one curve can be plotted on a subplot in multi-dimensional case, so any additional curve will throw a warning. Plot representation may not be as expected.>>> d31 = np.arange(bins1.size*bins2.size).reshape(bins1.size, bins2.size) >>> d32 = np.arange(bins1.size*bins2.size).reshape( ... bins1.size, bins2.size)*0.01 >>> pit7 = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(d31, bins=[bins1, bins2], ... legend='d31', index=0)], ... axnames=['egg', 'spam', 'bacon'], ptype='2D')]) >>> pit8 = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(d32, bins=[bins1, bins2], ... legend='d32', index=1)], ... axnames=['egg', 'spam', 'lobster'], ptype='2D')]) >>> splt78 = join(pit7, pit8) >>> print(f"{splt78!s}") class: <class 'valjean.javert.templates.PlotTemplate'> Subplot 0 axnames: ['egg', 'spam', 'bacon'], plot type: 2D Curve 0 legend: d31 index: 0 bins: [array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])] Subplot 1 axnames: ['egg', 'spam', 'lobster'], plot type: 2D Curve 0 legend: d32 index: 1 bins: [array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])]
It is also possible to mix 1D and 2D plots:
>>> splt27 = join(pit2, pit7) >>> print(f"{splt27!s}") class: <class 'valjean.javert.templates.PlotTemplate'> Subplot 0 axnames: ['egg', 'beer'], plot type: 1D Curve 0 legend: d12 index: 1 bins: [array([0, 1, 2, 3])] Subplot 1 axnames: ['egg', 'spam', 'bacon'], plot type: 2D Curve 0 legend: d31 index: 0 bins: [array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])]
- __init__(*, subplots, small_subplots=True, suppress_xaxes=False, suppress_legends=False, backend_kw=None)[source]
Construction of the PlotTemplate from a list of
SubPlotElements
.- Parameters:
subplots (list(SubPlotElements)) – list of sub-plots
small_subplots (bool) – draw additional subplots in smaller size than the first one, default =
True
suppress_xaxes (bool) – suppress label and ticks labels of the x-axis of subplots except the last one, default =
False
suppress_legends (bool) – suppress legend on all subplots except the first one, default =
False
backend_kw (dict) – dictionary with backend-specific options
- copy()[source]
Copy a
PlotTemplate
object.- Return type:
- join(*others)[source]
Join a given number a
PlotTemplate
to the current one.Only
PlotTemplate
with the same number of columns and same headers can be joined. The method returns the updated current one.- Parameters:
others (list(PlotTemplate)) – list of PlotTemplates to be join with the current PlotTemplate
- __repr__()[source]
Printing of
PlotTemplate
.
- __str__()[source]
Printing of
PlotTemplate
.
- data()[source]
Yield bytes representing self. Two
TableTemplate
objects containing equal data yield the same data.
- __eq__(other)[source]
Test for equality of self and another
PlotTemplate
.
- __ne__(other)[source]
Test for inequality of self and another
PlotTemplate
.
- __hash__ = None
- class valjean.javert.templates.TextTemplate(text)[source]
A container class that encapsulates text for the report.
The user has to write the text as a string. ReST markdown can be used as compilation is expected to be done by sphinx.
Note
Titles might not be well represented in a ReSt formatted TextTemplate: no knowledge of the current level of title, nor the associated symbol. Lists or enumerations might be more suitable.
As in the other templates, examples will focus on the concatenation (join) of different TextTemplate.
>>> ttplt1 = TextTemplate('Spam egg bacon') >>> print(f"{ttplt1!r}") <class 'valjean.javert.templates.TextTemplate'>(text='Spam egg bacon') >>> ttplt2 = TextTemplate('**Spam** egg bacon') >>> print(f"{ttplt2!r}") <class 'valjean.javert.templates.TextTemplate'>(text='**Spam** egg bacon') >>> ttplt3 = TextTemplate(r".. role:: hl\n\nsausage :hl:`tomato`") >>> ttplt1.join(ttplt3) >>> print(f"{ttplt1!r}") <class 'valjean.javert.templates.TextTemplate'>(text='Spam egg bacon.. role:: hl\\n\\nsausage :hl:`tomato`')
The sphinx compilation will fail there, as the are no empty line between the first and the second string. If you know some text will follow, think about the
\n
.>>> ttplt1 = TextTemplate('Spam egg bacon\n\n') >>> ttplt3 = TextTemplate('.. role:: hl\n\nsausage :hl:`tomato`\n\n') >>> ttplt1.join(ttplt3) >>> print(f"{ttplt1!r}") <class 'valjean.javert.templates.TextTemplate'>(text='Spam egg bacon\n\n.. role:: hl\n\nsausage :hl:`tomato`\n\n')
Test of the external function
join
:>>> ttplt4 = join(ttplt3, ttplt3) >>> print(f"{ttplt4!r}") <class 'valjean.javert.templates.TextTemplate'>(text='.. role:: hl\n\nsausage :hl:`tomato`\n\n.. role:: hl\n\nsausage :hl:`tomato`\n\n')
The copy doesn’t affect the original:
>>> ttplt5 = ttplt2.copy() >>> ttplt5.text += ' sausage' >>> print(f"{ttplt2!r}") <class 'valjean.javert.templates.TextTemplate'>(text='**Spam** egg bacon') >>> print(f"{ttplt5!r}") <class 'valjean.javert.templates.TextTemplate'>(text='**Spam** egg bacon sausage')
- __init__(text)[source]
Construct the text to be sent to the report.
- Parameters:
text (str) – text to be written in the report
- __repr__()[source]
Print
TextTemplate
details.
- copy()[source]
Copy a
TextTemplate
object.- Return type:
- join(*others)[source]
Join a given number of
TextTemplate
to the current one.
- data()[source]
Yield bytes representing self. Two
TableTemplate
objects containing equal data yield the same data.
- __eq__(other)[source]
Test for equality of self and another
TextTemplate
.
- __hash__ = None
- __ne__(other)[source]
Test for inequality of self and another
TextTemplate
.
- valjean.javert.templates.join(*templates)[source]
Join a “list” of templates of same kind,
TableTemplate
orPlotTemplate
using the relatedjoin
methods.It returns a new templates (
TableTemplate
orPlotTemplate
).- Parameters:
templates (list(TableTemplate) or list(PlotTemplate)) – list of templates
- Return type:
See
TableTemplate
andPlotTemplate
for examples of use. Only few error cases will be shown here:>>> bins1, data11, data12 = np.arange(4), np.arange(4), np.arange(4)*10 >>> bins2, data2 = np.arange(5), np.arange(5)*0.5 >>> tablit = TableTemplate(bins1, data11, headers=['egg', 'spam']) >>> plotit = PlotTemplate(subplots=[SubPlotElements( ... curves=[CurveElements(data11, bins=[bins1], legend='d11')], ... axnames=['egg', 'spam'])]) >>> tit = join(tablit, plotit) Traceback (most recent call last): ... TypeError: Only a TableTemplate can be joined to another TableTemplate >>> tit = join(plotit, tablit) Traceback (most recent call last): ... TypeError: Only a PlotTemplate can be joined to another PlotTemplate