Ask Your Question

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

asked 2020-04-25 00:04:10 +0100

DerekH gravatar image

updated 2020-06-01 11:30:02 +0100

FrédéricC gravatar image

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)
G = P.hasse_diagram().to_undirected()

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/", 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 flag offensive close merge delete


You can do

P = posets.BooleanLattice(3)
H = P.hasse_diagram()
G = H.to_undirected()
David Coudert gravatar imageDavid Coudert ( 2020-04-25 10:42:02 +0100 )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?

DerekH gravatar imageDerekH ( 2020-04-26 01:21:18 +0100 )edit

1 Answer

Sort by » oldest newest most voted

answered 2020-04-25 11:51:33 +0100

Sébastien gravatar image

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 ''>

Only the graph has the attribute get_pos:

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

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 ''>

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

edit flag offensive delete link more


I see. Thank you.

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

DerekH gravatar imageDerekH ( 2020-04-26 01:16:07 +0100 )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
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
Sébastien gravatar imageSébastien ( 2020-04-26 09:47:40 +0100 )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.

DerekH gravatar imageDerekH ( 2020-04-27 16:27:26 +0100 )edit

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]}
Sébastien gravatar imageSébastien ( 2020-04-27 17:15:13 +0100 )edit

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

DerekH gravatar imageDerekH ( 2020-04-27 17:58:07 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2020-04-24 23:58:54 +0100

Seen: 507 times

Last updated: Apr 25 '20