Plotting¶
This notebook can be downloaded here
.
# The import will work if the package was installed using pip.
import pyrigi.frameworkDB as frameworks
import pyrigi.graphDB as graphs
from pyrigi import Graph, Framework
Methods Graph.plot()
and Framework.plot()
offer various plotting options.
The default behaviour is the following:
G = Graph([(0,1), (1,2), (2,3), (0,3)])
G.plot()
F = Framework(G, {0: (0,0), 1: (1,1), 2: (3,1), 3: (2,0)})
F.plot()
Graph layouts¶
By default, a placement is generated using spring_layout()
.
G = graphs.ThreePrism()
G.plot()
Other options use random_layout()
, circular_layout()
or planar_layout()
:
G.plot(layout="random")
G.plot(layout="circular")
G.plot(layout="planar")
One can also specify a placement of the vertices explicitly:
G.plot(placement={0: (0, 0), 1: (0, 2), 2: (2, 1), 3: (6, 0), 4: (6, 2), 5: (4, 1)})
Canvas options¶
The size of the canvas can be specified.
S = frameworks.Square()
S.plot(canvas_width=2)
S.plot(canvas_height=2)
S.plot(canvas_width=2, canvas_height=2)
Also the aspect ratio:
S.plot(aspect_ratio=0.4)
Formatting¶
There are various options to format a plot.
Vertex color/size or label color/size can be changed.
G = Graph([[0,1]])
formatting = {
"placement": {0: [0,0], 1: [1,0]},
"canvas_height": 1,
}
G.plot(vertex_labels=False, vertex_color='green', **formatting)
G.plot(vertex_size=1500, font_size=30, font_color='#FFFFFF', **formatting)
There are various styles of vertices and edges.
formatting["vertex_labels"] = False
G.plot(vertex_shape='s', edge_style='-', **formatting)
G.plot(vertex_shape='o', edge_style='--', **formatting)
G.plot(vertex_shape='^', edge_style='-.', **formatting)
G.plot(vertex_shape='>', edge_style=':', **formatting)
G.plot(vertex_shape='v', edge_style='solid', **formatting)
G.plot(vertex_shape='<', edge_style='dashed', **formatting)
G.plot(vertex_shape='d', edge_style='dashdot', **formatting)
G.plot(vertex_shape='p', edge_style='dotted', **formatting)
G.plot(vertex_shape='h', edge_width=3, **formatting)
G.plot(vertex_shape='8', edge_width=5, **formatting)
Edge coloring¶
The color of all edges can be changed.
P = graphs.Path(6)
formatting = {
"placement": {v: [v, 0] for v in P.vertex_list()},
"canvas_height": 2,
"edge_width": 5,
}
P.plot(edge_color='red', **formatting)
If a partition of the edges is specified, then each part is colored differently.
P.plot(edge_color=[[[0, 1], [2, 3]], [[1, 2]], [[5, 4], [4, 3]]], **formatting)
If the partition is incomplete, the missing edges are black.
P.plot(edge_color=[[[0, 1], [2, 3]], [[5, 4], [4, 3]]], **formatting)
Visually distinct colors are generated using the package distinctipy
.
P30 = graphs.Path(30)
P30.plot(
vertex_size=15,
vertex_labels=False,
edge_color=[[e] for e in P30.edge_list()],
edge_width=3
)
Another possibility is to provide a dictionary assigning to a color a list of edges. Missing edges are again black.
P.plot(
edge_color={
"yellow": [[0, 1], [2, 3]],
"#ABCDEF": [[5, 4], [4, 3]]
},
**formatting
)
Framework plotting¶
Currently, only plots of frameworks in the plane are implemented.
F = frameworks.Complete(9)
F.plot()
The same formatting options as for graphs are available for frameworks.
F = frameworks.Complete(9)
F.plot(
vertex_labels=False,
vertex_color='#A2B4C6',
edge_style='dashed',
edge_width=2,
edge_color={"pink": [[0,1],[3,6]], "lightgreen": [[2, 3], [3, 5]]}
)
Infinitesimal Flexes¶
It is possible to include infinitesimal flexes in the plot. With the keyword
inf_flex=n
, we can pick the n
-th nontrivial infinitesimal flex from
a basis of the rigidity matrix’s kernel. There are several keywords that allow
us to alter the style of the drawn arrows.
G = Graph([[0, 1], [0, 2], [1, 2], [2, 3], [2, 4], [3, 4]])
p = {0: [6, 8], 1: [6, -14], 2: [0, 0], 3: [-4, 4], 4: [-4, -4]}
F = Framework(G, p)
F.plot(
inf_flex=0,
flex_width=4,
flex_length=0.25,
flex_color="darkgrey",
flex_style="-",
flex_arrowsize=15
)
It is also possible to provide a specific infinitesimal flex with the following chain of commands:
F = frameworks.ThreePrism(realization="flexible")
flex = F.nontrivial_inf_flexes()[0]
F.plot(inf_flex=flex)
It is important to use the same order of the vertices of F
as Graph.vertex_list()
when
providing the infinitesimal flex as a Matrix
. To circumvent that,
we also support adding an infinitesimal flex as a dict[Vertex, Vector]
:
F = frameworks.Square()
flex = {0: (1, -1), 1: (1, 1), 2: (-1, 1), 3: (-1, -1)}
F.plot(inf_flex=flex)