如何在python igraph中使用自定义字体的顶点标签?

时间:2014-06-15 15:55:13

标签: python igraph

在R igraph中,有一种简单的方法可以在图形图上为顶点标签和其他文本设置自定义字体:

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

然而,正如我所见,vertex_label_family参数在python igraph中不可用。我花了一些时间才找到一些解决方法来设置标签字体,所以我会在这里发布我的解决方案。我想知道,如果有更优雅或更简单的解决方案。首先,我尝试在igraph图对象的上下文中调用cairo的context.select_font_face(),但遗憾的是draw()中的igraph.drawing.graph.DefaultGraphDrawer()函数会在每个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()

所以这不起作用。我将发布一个有效的简单解决方案。

1 个答案:

答案 0 :(得分:4)

我可以设法设置顶点标签的字体,并用新的DefaultGraphDrawer类替换它,它只与原始字体有两行不同。我只是从我的python发行版的site-packages目录中复制了igraph/drawing/graph.py文件,并删除了除DefaultDraphDrawer之外的所有其他类。导入后,我添加了一行来导入AbstractCairoGraphDrawer,并修改了__all__[]列表:

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

然后我重命名了DefaultGraphDrawer类,修改了它的字体选择部分:

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)
        ...
    ...

我把这个文件(ig_drawing.py)放在我模块的目录中,然后导入它。我可以通过将修改后的类作为drawing_factory函数的plot()参数传递来设置任何字体:

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()

如果您未设置graph.font,则使用" sans-serif"。但是,如果您提供一个不存在的字体名称,那么没有错误消息它会回退到您系统的默认sans字体。

它看起来像默认的" sans-serif"字体在igraph中是硬编码的,在使用cairo surface和svg绘制函数时都是如此。有没有更简单的方法来改变这个?