[igraph] how to plot graph on matplotlib figure?

627 views
Skip to first unread message

Diederik van Liere

unread,
Jun 28, 2010, 4:38:53 AM6/28/10
to igrap...@nongnu.org
Hi Igraph developers!

I have a short question that I have struggling with and seems to be really straightforward but I can't find the answer.

I would like to add my graph to a matplotlib figure but don't know how. Could somebody please email me a code snippet showing how to do this? Or, if this is not possible, how can you add titles, etc to an igraph.plot object?

Best,

Diederik

Tamas Nepusz

unread,
Jun 28, 2010, 5:01:10 AM6/28/10
to Help for igraph users
Hi,

> I would like to add my graph to a matplotlib figure but don't know how. Could somebody please email me a code snippet showing how to do this? Or, if this is not possible, how can you add titles, etc to an igraph.plot object?

As for matplotlib, I don't know the answer off the top of my head, but I guess it can be done with matplotlib's Cairo backend. igraph's plot() function and the Plot() class supports a keyword argument named "target", which can accept an arbitrary Cairo surface to plot on. If you can get the Cairo surface matplotlib plots on somehow, you can construct a Plot instance in igraph using this surface, call the .add() method of the Plot instance to add your graph to the plot and there you go. Alternatively, you can construct a Plot instance on its own and pass its .surface attribute to matplotlib if matplotlib supports that.

Another option I can think of right now for plotting a title to an igraph.plot object is to implement a plottable Title class yourself. If you dig deeper into igraph's drawing internals (in the API documentation of the Plot class), you will find that you can add arbitrary objects to a Plot instance, and igraph will call the __plot__ method of these objects when the plot is drawn. So, if you do something like this:

class Label(object):
def __init__(self, text):
self.text = text

def __plot__(self, context, bbox, palette):
# Call some Cairo methods on the given Cairo context to draw self.text
# into the bounding box given by `bbox`
[...]

then the following might work:

plot = Plot(bbox=(600, 600))
plot.add(your_graph)
title_label = Label("here comes the title of the plot")
plot.add(title_label, bbox=BoundingBox(0, 0, 600, 20))
plot.save()

I've never tried it, but if you manage to come up with a solution, please let me know and I will add it to igraph 0.6.

--
Tamas


_______________________________________________
igraph-help mailing list
igrap...@nongnu.org
http://lists.nongnu.org/mailman/listinfo/igraph-help

Tamas Nepusz

unread,
Jun 30, 2010, 10:39:14 AM6/30/10
to Help for igraph users
Hi Diederik,

> I would like to add my graph to a matplotlib figure but don't know how.

I played around a bit with matplotlib today and this is what I came up
with (see the attachment). It works only for Cairo-based Matplotlib
backends as igraph supports plotting on Cairo contexts only.

--
Tamas

igraph_mpl.py

Diederik van Liere

unread,
Jul 5, 2010, 8:41:11 AM7/5/10
to Help for igraph users
Hi Tamas,

Thanks for your code snippet, however it does not work for me. I get a:

RendererCairo instance has no attribute 'ctx'

message, i am using igraph 0.5.3 and matplotlib 0.99.3 and cairo 1.8.10

what should I do to fix this?
best,
Diederik


Tamas Nepusz

unread,
Jul 5, 2010, 8:44:48 AM7/5/10
to Help for igraph users
Hi Diederik,

Hmmm, 'ctx' is an undocumented attribute of RendererCairo that should
hold the Cairo context on which matplotlib is drawing. It worked for me
with my version of Matplotlib (0.98.5.2), it looks like they have
changed something between Matplotlib 0.98.5.2 and 0.99.3. I'll try to
get hold of the most recent version and see what the new name of this
attribute is. Maybe try replacing 'renderer.ctx' with 'renderer.gc.ctx'
first, this seems to work in 0.99.1

--
Tamas

Diederik van Liere

unread,
Jul 5, 2010, 9:00:54 AM7/5/10
to Help for igraph users
Hi Tamas,

Indeed, renderer.gc.ctx does work, thanks so much for your help!!!!!

best,

Diederik

Diederik van Liere

unread,
Jul 5, 2010, 11:27:19 AM7/5/10
to Help for igraph users
Hi Tamas,

Just one final question about plotting a graph using matplotlib. It seems that the visual_style dictionary is not passed along to the renderer. Is this a limitation of using matplotlib or should the code snippet be extended with support for a visual_style dictionary?

Thanks so much!

best,
Diederik

Tamas Nepusz

unread,
Jul 5, 2010, 12:34:37 PM7/5/10
to Help for igraph users
> Just one final question about plotting a graph using matplotlib. It seems
> that the visual_style dictionary is not passed along to the renderer.
Errrm, can you show me a code snippet? I don't really know what you mean
by the visual_style dictionary.

Diederik van Liere

unread,
Jul 5, 2010, 4:28:11 PM7/5/10
to Help for igraph users

I used the following snippet to render graphs using igraph:

visual_style = {}

visual_style["vertex_size"] = [20] * ego.vcount()

visual_style["layout"] = layout

visual_style["bbox"] = (800, 800)

visual_style["margin"] = 20

visual_style["vertex_label"] = ['' for i in range(ego.vcount())]

fig = igraph.plot(ego, **visual_style)            

    

but when I pass the visual_style dict to the matplotlib renderer like this (based on your codesnippet):


graph_artist = GraphArtist(ego, (10, 10, 550, 430), **visual_style) 


then the dict is not interpreted and the visual styles do not have any effect.


best,


Diederik

Tamas Nepusz

unread,
Jul 5, 2010, 5:40:51 PM7/5/10
to Help for igraph users
> but when I pass the visual_style dict to the matplotlib renderer like this (based on your codesnippet):
Replace the following line in the draw() method:

self.graph.__plot__(renderer.gc.ctx, self.bbox, self.palette)

The replacement should be as follows:

self.graph.__plot__(renderer.gc.ctx, self.bbox, self.palette, *self.args, **self.kwds)

--
T.

Reply all
Reply to author
Forward
0 new messages