# Attribute error: "'Graphics' object has no attribute 'get_pos'" with plotting Hasse diagram of poset

So I am trying to obtain the position dictionary used for displaying a poset P that can be used in the plotting of the Hasse diagram of P through the hasse_diagram() function.

To clarify, if I run the following code:

P = posets.BooleanLattice(3)
P.plot()
G = P.hasse_diagram().to_undirected()
G.plot()


The locations of the vertices of G do not line up with where the corresponding elements of the poset were. I know that we can save the position dictionary for graphs, but for whatever reason, I'm struggling with obtaining the position dictionary of elements in a poset. (With the specific posets I am working with, maintaining the position when obtaining the undirected Hasse diagram is important because I need a particular planar embedding which is not being preserved if I simply use the hasse_diagram() function in its canned form).

In the finite posets SageMath documentation, the plot() function says that it also accepts all options of GenericGraph.plot which should include the save_pos option and get_pos(). However, when I run

P = posets.BooleanLattice(3)
Pplot = P.plot(save_pos=True)
G = P.hasse_diagram().to_undirected()
position = Pplot.get_pos()
G.plot(pos = position)


I get an attribute error:

Error in lines 4-4
Traceback (most recent call last):
File "/cocalc/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 1234, in execute
flags=compile_flags), namespace, locals)
File "", line 1, in <module>
AttributeError: 'Graphics' object has no attribute 'get_pos'


Is there any way to extract a position dictionary of a graphics object corresponding to the Hasse diagram of a poset?

edit retag close merge delete

You can do

P = posets.BooleanLattice(3)
H = P.hasse_diagram()
H.plot(save_pos=True)
G = H.to_undirected()
G.plot(pos=H.get_pos())

( 2020-04-25 10:42:02 +0200 )edit

If you were to insert P.plot() after defining P, this is what I want to record the positions of. In this case, this saves the positions of the Hasse diagram which are different from those used in plotting P. Does that make sense?

( 2020-04-26 01:21:18 +0200 )edit

Sort by » oldest newest most voted

There is a difference between the graph and the plot of the graph:

sage: the_graph = graphs.PetersenGraph()
sage: the_plot_of_the_graph = the_graph.plot()


which are two different objects:

sage: type(the_graph)
<class 'sage.graphs.graph.Graph'>
sage: type(the_plot_of_the_graph)
<class 'sage.plot.graphics.Graphics'>


Only the graph has the attribute get_pos:

sage: hasattr(the_graph, 'get_pos')
True
sage: hasattr(the_plot_of_the_graph, 'get_pos')
False


Notice that the plot of a circle is also an instance of a Graphics object:

sage: P = circle((0,0), 1).plot()
sage: type(P)
<class 'sage.plot.graphics.Graphics'>


so there is no reason for a Graphics object to have the get_pos attribute.

more

I see. Thank you.

So there is no way to obtain the positions used for displaying the Hasse diagram of the poset?

( 2020-04-26 01:16:07 +0200 )edit

To get the positions, you may use the hasse diagram (which is a graph), as in David's comment:

sage: P = posets.BooleanLattice(3)
sage: H = P.hasse_diagram()
sage: type(H)
<class 'sage.graphs.digraph.DiGraph'>
sage: H.get_pos() is None
True
sage: H.plot(save_pos=True)
sage: H.get_pos()
{0: [0.5890724969789229, -0.20715251993436856],
1: [1.5189897865027617, -0.2000526767515886],
2: [0.750749760733092, 0.7384082725454604],
3: [1.7233998297698385, 0.7412892385733717],
4: [1.136666616696451, -0.7457364942062225],
5: [2.08715454762865, -0.7443106906052225],
6: [1.293314144199393, 0.23138946724390927],
7: [2.2552211258760773, 0.18616540313465754

( 2020-04-26 09:47:40 +0200 )edit

Thank you for your comment! So this makes sense if I want to obtain the positions of H, but I was actually hoping to obtain the positions used when executing P.plot() so I can use those in constructing the hasse diagram graph via P.hasse_diagram(). Ultimately, I want the vertices of H to be in the same position as their corresponding element of the poset P is placed when displaying the poset via P.plot(). I hope that makes sense.

( 2020-04-27 16:27:26 +0200 )edit
1

Ok, I see. Looking at the source code of P.plot() which you can do by doing P.plot??, I understand that you are interested in the positions when using the acyclic layout of a digraph. You may obtain those positions by doing this:

sage: P = posets.BooleanLattice(3)
sage: H = P.hasse_diagram()
sage: the_plot = H.plot(layout='acyclic', save_pos=True)
sage: H.get_pos()
{0: [99, 18],
1: [27, 90],
2: [99, 90],
4: [171, 90],
3: [27, 162],
5: [99, 162],
6: [171, 162],
7: [99, 234]}

( 2020-04-27 17:15:13 +0200 )edit

You are my hero! Worked like a charm. Thank you so much. I greatly appreciate it.

( 2020-04-27 17:58:07 +0200 )edit