1
votes

In R igraph, there is an easy way to set a custom typeface for vertex labels and other texts on graph plots:

plot(G,vertex.label.family="DINPro")

However as I see, vertex_label_family parameter is not available in python igraph. It took some time while I have found some workaround to be able to set the label font, so I will post my solution here. And I'm wondering, if there are more elegant or easier solutions. First I tried to call cairo's context.select_font_face() on the igraph plot object's context, but sadly the draw() function in igraph.drawing.graph.DefaultGraphDrawer() overwrites it in each plot.redraw():

lo = graph.layout_fruchterman_reingold()
sf = cairo.PDFSurface("test.pdf",1280,1280)
bx = igraph.drawing.utils.BoundingBox(10, 10, 1260, 1260)
plot = igraph.plot(graph,layout=lo,target=sf,bbox=bx)
plot._ctx.select_font_face("DINPro", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
plot.redraw()
plot.save()

So this doesn't work. I will post a simple solution what works.

1

1 Answers

4
votes

I could manage to set the typeface of vertex labels with replacing the DefaultGraphDrawer class with a new one, which only differs in two lines from the original. I simply copied the igraph/drawing/graph.py file from the site-packages directory of my python distribution, and I deleted every other classes except the DefaultDraphDrawer. After the imports, I added a line to import the AbstractCairoGraphDrawer, and modified the __all__[] list:

from igraph.drawing.graph import AbstractCairoGraphDrawer
__all__ = ["DefaultGraphDrawerFFsupport"]

Then I renamed the DefaultGraphDrawer class, modified the font selection part of it:

class DefaultGraphDrawerFFsupport(AbstractCairoGraphDrawer):
    ...
    def draw(...):
        ...
        fontFamily = graph.font if hasattr(graph, "font") else "sans-serif"
        context.select_font_face(fontFamily, cairo.FONT_SLANT_NORMAL, \
             cairo.FONT_WEIGHT_NORMAL)
        ...
    ...

I put this file (ig_drawing.py) in the directory of my module, and imported it. The I could set any typeface by passing the modified class as drawing_factory parameter for the plot() function:

from ig_drawing import *
lo = graph.layout_fruchterman_reingold()
sf = cairo.PDFSurface("test.pdf",1280,1280)
bx = igraph.drawing.utils.BoundingBox(10, 10, 1260, 1260)
df = igraph.drawing.graph.DefaultGraphDrawer(ctx, bx)
graph.font = "DINPro"
plot = graph.plot(graph,layout=lo,target=sf,bbox=bx,vertex_label=graph.vs["label"],drawer_factory=DefaultGraphDrawerFFsupport)
a.plot.save()

In case you don't set the graph.font, it uses "sans-serif". But also if you give a non existing font name, then without error message it falls back to your system's default sans font.

It looks like the default "sans-serif" typeface is hardcoded in igraph, both in plotting functions using cairo surfaces and svg. Any simpler way to change this?