Displaying tabulated data¶
This page contains several examples how to use the classes in finesse.utilities.tables
The first class is Table. It is intended for already readable data, that means strings or objects with a useful __str__ method.
import numpy as np
import finesse
from finesse.utilities.tables import Table, NumberTable
data = [['a', 'b', 'c'],
[1,2,3],
[4,5,6]
]
tab = Table(data)
The table can be displayed with pretty printing or as html. The print method will prefer html display if thwat is supported and fall back to a sring representation if not. Calling the built-in print function always uses the string version.
tab.print()
a | b | c |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
print(tab)
┌───┬───┬───┐
│ a │ b │ c │
╞═══╪═══╪═══╡
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
└───┴───┴───┘
By default the first row is considered a header. This can also be enabled for the first column or disabled.
print(Table(data, headerrow=True, headercolumn=True))
┌───╥───┬───┐
│ a ║ b │ c │
╞═══╬═══╪═══╡
│ 1 ║ 2 │ 3 │
├───╫───┼───┤
│ 4 ║ 5 │ 6 │
└───╨───┴───┘
print(Table(data, headerrow=False, headercolumn=True))
┌───╥───┬───┐
│ a ║ b │ c │
├───╫───┼───┤
│ 1 ║ 2 │ 3 │
├───╫───┼───┤
│ 4 ║ 5 │ 6 │
└───╨───┴───┘
print(Table(data, headerrow=False, headercolumn=True))
┌───╥───┬───┐
│ a ║ b │ c │
├───╫───┼───┤
│ 1 ║ 2 │ 3 │
├───╫───┼───┤
│ 4 ║ 5 │ 6 │
└───╨───┴───┘
The textcolor, backgroundcolor and the text alignment can be changed. They can be specified in four different ways:
A single value that will be applied to all cells
One value per row in a nested list
One value per column in a nested list
A value for every cell in an array with the same dimensions as the data
The colors must be defined as RGB values, possible alignments are “left”, “right” and “center”.
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
Table(data, color=red)
a | b | c |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
Table(data,
color=[
[red],
[green],
[blue]
])
a | b | c |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
Table(data,
color=[
[red, green, blue]
])
a | b | c |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
Table(data,
color=[
[red, green, blue],
[blue, green, red],
[green, red, blue]
])
a | b | c |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
Table(data, backgroundcolor=green)
a | b | c |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
If any number of the RGB triple is smaller than zero, it is treated as if no color was given.
Table(data,
color=[
[blue, (-1,0,0), red]
])
a | b | c |
---|---|---|
1 | 2 | 3 |
4 | 5 | 6 |
tab=Table([['abc','def','ghi'],['x','y','z']], alignment=[['left','right','center']])
print(tab)
tab.print()
┌─────┬─────┬─────┐
│ abc │ def │ ghi │
╞═════╪═════╪═════╡
│ x │ y │ z │
└─────┴─────┴─────┘
abc | def | ghi |
---|---|---|
x | y | z |
It is also possible to generate latex code for the table.
print(tab.latex())
\begin{table}
\begin{tabular}{|l|r|c|}
\hline
abc & def & ghi\\
\hline
x & y & z\\
\hline
\end{tabular}
\end{table}
If the table cells have colored text, the xcolor package must be used in the latex file, the backgroundcolor is not used.
For handling different alignments in a column the multicolumn command is used.
tab = Table(
[
['abc','def','ghi'],
['x','y','z']
],
color=[
[red, green, blue],
[blue, green, red]
],
alignment=[
['left','right','center'],
['right', 'left', 'center']
]
)
print(tab.latex())
\begin{table}
\definecolor{color000000255}{RGB}{000, 000, 255}
\definecolor{color000255000}{RGB}{000, 255, 000}
\definecolor{color255000000}{RGB}{255, 000, 000}
\begin{tabular}{|l|r|c|}
\hline
\textcolor{color255000000}{abc} & \textcolor{color000255000}{def} & \textcolor{color000000255}{ghi}\\
\hline
\multicolumn{1}{|r|}{\textcolor{color000000255}{x}} & \multicolumn{1}{|l|}{\textcolor{color000255000}{y}} & \textcolor{color255000000}{z}\\
\hline
\end{tabular}
\end{table}
You can also save the data of the table as a csv file using the syntax of the csv package. The file will not contain any formatting or color information. The function returns the used csv writer, so you can write further data to the file.
import sys
tab.write_csv(sys.stdout)
abc,def,ghi
x,y,z
<_csv.writer at 0x7d7489d750c0>
If you want to process some other data as a table or change how something is shown, you can create a new class inheriting from Table and overload the necessary methods. One such class already exists: NumberTable. It displays data only containing numbers with string headers.
data = np.random.random((2,3))
NumberTable(data)
0.0032743891324292784 | 0.541515415447959 | 0.28780392916561615 |
0.5685059181255122 | 0.9413666277334634 | 0.27851377245915765 |
NumberTable(data, colnames=['a','b','c'])
a | b | c |
---|---|---|
0.0032743891324292784 | 0.541515415447959 | 0.28780392916561615 |
0.5685059181255122 | 0.9413666277334634 | 0.27851377245915765 |
NumberTable(data, rownames=['x','y'])
x | 0.0032743891324292784 | 0.541515415447959 | 0.28780392916561615 |
---|---|---|---|
y | 0.5685059181255122 | 0.9413666277334634 | 0.27851377245915765 |
NumberTable(data, rownames=['x','y'], colnames=['a','b','c'])
a | b | c | |
---|---|---|---|
x | 0.0032743891324292784 | 0.541515415447959 | 0.28780392916561615 |
y | 0.5685059181255122 | 0.9413666277334634 | 0.27851377245915765 |
You can format the numbers in several wayswith a python formatting string or a function that transforms numbers to strings. These can be given for every cell at once, column- or row-wise or for every cell individually.
print(
NumberTable(
data,
numfmt='{:.5g}'
)
)
┌───────────┬─────────┬─────────┐
│ 0.0032744 │ 0.54152 │ 0.2878 │
├───────────┼─────────┼─────────┤
│ 0.56851 │ 0.94137 │ 0.27851 │
└───────────┴─────────┴─────────┘
print(
NumberTable(
data,
numfmt=lambda x: round(x,2)
)
)
┌──────┬──────┬──────┐
│ 0.0 │ 0.54 │ 0.29 │
├──────┼──────┼──────┤
│ 0.57 │ 0.94 │ 0.28 │
└──────┴──────┴──────┘
print(
NumberTable(
data,
numfmt=[
['{:.5g}','{:.2g}','{:.1g}']
]
)
)
┌───────────┬──────┬─────┐
│ 0.0032744 │ 0.54 │ 0.3 │
├───────────┼──────┼─────┤
│ 0.56851 │ 0.94 │ 0.3 │
└───────────┴──────┴─────┘
print(
NumberTable(
data,
numfmt=[
['{:.5g}'],
['{:.2g}']
]
)
)
┌───────────┬─────────┬────────┐
│ 0.0032744 │ 0.54152 │ 0.2878 │
├───────────┼─────────┼────────┤
│ 0.57 │ 0.94 │ 0.28 │
└───────────┴─────────┴────────┘
print(
NumberTable(
data,
numfmt=[
['{:.5g}','{:.2g}','{:.1g}'],
['{:.1e}',lambda x: round(x,2), lambda x: str(x**2)]
]
)
)
┌───────────┬──────┬─────────────────────┐
│ 0.0032744 │ 0.54 │ 0.3 │
├───────────┼──────┼─────────────────────┤
│ 5.7e-01 │ 0.94 │ 0.07756992144943144 │
└───────────┴──────┴─────────────────────┘
You can also color the numbers and their background by applying a function to the data array. It has to have the structure of a matplotlib colormap.
import matplotlib as mpl
cmap1 = mpl.colormaps.get_cmap('viridis')
cmap2 = mpl.colormaps.get_cmap('Greys')
tab = NumberTable(
data,
rownames=['x','y'],
colnames=['a','b','c'],
numfmt='{:.5g}',
colfunc = cmap1,
bgcolfunc = cmap2
)
tab.print()
a | b | c | |
---|---|---|---|
x | 0.0032744 | 0.54152 | 0.2878 |
y | 0.56851 | 0.94137 | 0.27851 |
As the colormaps expect values between 0 and 1, you can provide a normalization function.
NumberTable(
[[200,500,-300]],
colfunc=cmap1,
norm=mpl.colors.Normalize(vmin=-300, vmax=500))
200 | 500 | -300 |
As NumberTable is a child class of Table, it has the same display functions.
print(tab.latex())
\begin{table}
\definecolor{color017017017}{RGB}{017, 017, 017}
\definecolor{color031154138}{RGB}{031, 154, 138}
\definecolor{color031161136}{RGB}{031, 161, 136}
\definecolor{color054092141}{RGB}{054, 092, 141}
\definecolor{color055090140}{RGB}{055, 090, 140}
\definecolor{color068001084}{RGB}{068, 001, 084}
\definecolor{color131131131}{RGB}{131, 131, 131}
\definecolor{color138138138}{RGB}{138, 138, 138}
\definecolor{color209209209}{RGB}{209, 209, 209}
\definecolor{color211211211}{RGB}{211, 211, 211}
\definecolor{color216226025}{RGB}{216, 226, 025}
\definecolor{color255255255}{RGB}{255, 255, 255}
\begin{tabular}{|c|c|c|c|}
\hline
& a & b & c\\
\hline
x & \multicolumn{1}{|r|}{\textcolor{color068001084}{0.0032744}} & \multicolumn{1}{|r|}{\textcolor{color031154138}{0.54152}} & \multicolumn{1}{|r|}{\textcolor{color054092141}{0.2878}}\\
\hline
y & \multicolumn{1}{|r|}{\textcolor{color031161136}{0.56851}} & \multicolumn{1}{|r|}{\textcolor{color216226025}{0.94137}} & \multicolumn{1}{|r|}{\textcolor{color055090140}{0.27851}}\\
\hline
\end{tabular}
\end{table}
tab.write_csv(sys.stdout);
,a,b,c
x,0.0032744,0.54152,0.2878
y,0.56851,0.94137,0.27851
These classes are used in finesse by several functions to display information. For example the distances matrix of a model can be shown in table format. The function supports keyword arguments for NumberTable to customize the table.
model = finesse.Model()
model.parse("""
### L0 -> BS -> YARM of ET-LF
# input
l L0 P=1
s l0 L0.p1 BS.p1 L=10
# Main beam splitter
bs BS T=0.5 L=37.5u alpha=60
s BSsub1 BS.p3 BSAR1.p1 L=0.07478 nr=&nsilica
s BSsub2 BS.p4 BSAR2.p1 L=0.07478 nr=&nsilica
bs BSAR1 R=50u L=0 alpha=-36.6847
bs BSAR2 R=50u L=0 alpha=36.6847
# Y arm telescope
s lBS_ZM1 BS.p2 ZM1.p1 L=70
bs ZM1 T=250u L=37.5u Rc=-50
s lZM1_ZM2 ZM1.p2 ZM2.p1 L=50
bs ZM2 T=0 L=37.5u Rc=-82.5
s lZM2_ITMlens ZM2.p2 ITM_lens.p1 L=52.5
lens ITM_lens 75
s lITM_th2 ITM_lens.p2 ITMAR.p1 L=0
# Y arm input mirror
m ITMAR R=0 L=20u
s ITMsub ITMAR.p2 ITM.p1 L=0.2 nr=&nsilicon
m ITM T=7000u L=37.5u Rc=-5580
# Y arm length
s l_arm ITM.p2 ETM.p1 L=10k
# Y arm end mirror
m ETM T=6u L=37.5u Rc=5580
s ETMsub ETM.p2 ETMAR.p1 L=0.2 nr=&nsilicon
m ETMAR R=0 L=500u
# SRM
s lBS_SRM BSAR2.p3 SRM.p1 L=10
m SRM T=0.2 L=0 Rc=-9410
s SRMsub SRM.p2 SRMAR.p1 L=0.0749 nr=&nsilicon
m SRMAR R=0 L=50n
# cavities
cav cavARM ITM.p2
cav cavSRC SRM.p1 ITM.p1.i
var nsilica 1.44963098985906
var nsilicon 3.42009
lambda(1550n)
""")
ps = model.propagate_beam(model.ITM.p1.o, model.SRM.p1.i)
import matplotlib as mpl
cmap = mpl.colormaps.get_cmap('viridis')
norm = mpl.colors.Normalize(vmin=-200, vmax=200)
tab = ps.distances_matrix_table(
colfunc = cmap,
norm = norm
)
tab.print()
ITM | ITMAR | ITM_lens | ZM2 | ZM1 | BS | BSAR2 | SRM | |
---|---|---|---|---|---|---|---|---|
ITM | 0 m | 200 mm | 200 mm | 52.7 m | 102.7 m | 172.7 m | 172.77 m | 182.77 m |
ITMAR | -200 mm | 0 m | 0 m | 52.5 m | 102.5 m | 172.5 m | 172.57 m | 182.57 m |
ITM_lens | -200 mm | 0 m | 0 m | 52.5 m | 102.5 m | 172.5 m | 172.57 m | 182.57 m |
ZM2 | -52.7 m | -52.5 m | -52.5 m | 0 m | 50 m | 120 m | 120.07 m | 130.07 m |
ZM1 | -102.7 m | -102.5 m | -102.5 m | -50 m | 0 m | 70 m | 70.075 m | 80.075 m |
BS | -172.7 m | -172.5 m | -172.5 m | -120 m | -70 m | 0 m | 74.78 mm | 10.075 m |
BSAR2 | -172.77 m | -172.57 m | -172.57 m | -120.07 m | -70.075 m | -74.78 mm | 0 m | 10 m |
SRM | -182.77 m | -182.57 m | -182.57 m | -130.07 m | -80.075 m | -10.075 m | -10 m | 0 m |