2014-06-15 125 views
1

就R的igraph,沒有設置頂點的標籤和其他文本的自定義字體在圖形繪製的簡單方法:如何在python igraph中使用自定義字體作爲頂點標籤?

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

但是我看到,vertex_label_family參數是不是在蟒蛇的igraph可用。花了一些時間,我找到了一些可以設置標籤字體的解決方法,所以我會在這裏發佈我的解決方案。我想知道,如果有更優雅或更簡單的解決方案。首先,我想呼籲的igraph情節對象的上下文開羅context.select_font_face(),但遺憾的是在igraph.drawing.graph.DefaultGraphDrawer()draw()函數覆蓋它在每個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() 

所以這是行不通的。我會發佈一個簡單的解決方案。

回答

3

我可以設置頂點標籤的字體,用一個新的替換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,它採用「無襯線」。但是,如果您提供一個不存在的字體名稱,則不會出現錯誤消息,而是返回到系統的默認無字體字體。

它看起來像默認的「無襯線」字體在igraph中硬編碼,無論是在使用cairo曲面和svg的繪圖功能。任何更簡單的方法來改變這一點?

+0

你是對的,不幸的是,'sans-serif'字體當前被硬編碼爲'DefaultGraphDrawer'。我想解決這個問題已經有一段時間了,但是「正確地」這樣做意味着將'DefaultGraphDrawer'中的所有標籤繪製代碼移動到'AbstractVertexDrawer'中(因爲恕我直言,這是它在邏輯上屬於的地方),而且我從未真正找到空閒時間。你的解決方法很好,我暫時無法想到任何簡單的事情。讓我知道你是否有興趣整理你的代碼,以便它可以包含在下一個版本中。 –

+0

@Tamás:謝謝您的回覆!是的,將它包含在即將發佈的版本中將會很好。我還有一個想法可以包含在igraph中,我願意談論它,並在可能的情況下做出貢獻。 – deeenes

相關問題