2009-11-05 85 views
4

這是一個非常具體的信息挑戰,儘管這個問題的關鍵是如何使用matplotlib,cario或其他python庫創建詞之間的拱形。在Python中的拱形關係圖

給出以下數據結構。

我,你,7 | 我,蘋果,9 | apple,you,1 | 自行車,我,5

名稱將水平顯示的關係最大的名稱比其他人大,然後將名稱之間加權拱。一個10加重的拱會比5加重的拱厚兩倍。

靈感來自:類似diverstiy。 http://similardiversity.net/

讓挑戰開始吧!

+0

這是一個有趣的想法。你需要它是基於矢量的縮放/打印,還是位圖?我擔心這次Matplotlib將會有點難以做出這樣的圖表。 – RedGlyph 2009-11-05 12:25:40

+0

基於矢量將是我認爲最好的。是的,這對於cario來說更像是一份工作。超越了數學制圖的世界。有關如何處理文本和貝塞爾曲線/拱形以獲得這種效果的任何想法? – 2009-11-05 12:52:11

回答

1

有幾個庫,其中至少有一個依賴於Matplotlib,它可以做你想做的。我建議Networkx(www.networkx.lanl.gov)構建您的圖形結構,然後您可以使用它調用相關的Matplotlib方法進行繪圖。 Networkx和Matplotlib一起工作得很好。

import networkx as NX 
import matplotlib.pyplot as PLT 
Gh = NX.Graph() 
Gh.add_edge("You", "Bike", weight=1.0) 
Gh.add_edge("Bike", "Apple", weight=0.9) 
Gh.add_edge("Me", "Bike", weight=1.1) 
all_nodes = Gh.nodes() 
# to scale node size with degree: 
scaled_node_size = lambda(node) : NX.degree(Gh, node) * 700 
position = NX.spring_layout(Gh) # just choose a layout scheme 
NX.draw_networkx_nodes(Gh, position, node_size=map(scaled_node_size, all_nodes)) 
NX.draw_network_edges(Gh, position, Gh.edges(), width=1.0, alpha=1.0, edge_color="red") 
# now for the Matplotlib part: 
PLT.axis("off") 
PLT.show() 

正如你所看到的,你可以通過應用來改變「重量」參數任何的「邊緣」的方法,用同樣的方法,因爲我做到了節點縮放因子縮放邊緣。

我也推薦pygraphviz(顯然使用graphviz作爲它的後端)。它與Netwworkx(同樣的首席開發者)非常相似。

0

我真的不知道難度或挑戰在哪裏。所有你需要的是一個圖形庫,可以繪製文本和半圈,這幾乎是一切可能。不需要貝塞爾曲線。例如,您可以簡單地創建一個SVG文件(然後您甚至不需要任何庫,並可以很好地將其嵌入到網頁中,並使用一些JavaScript來使其交互)。

實際繪圖很簡單:圓的中心位於兩個單詞的中間,半徑是它們之間距離的一半。然後您可以調整筆畫以反映其他數量。

+0

我想我正在尋找洞察人們推薦哪些軟件包以及哪些功能最適合使用。這不是固有的困難,但找到最好的包和正確的功能是... – 2009-11-05 15:13:19

+0

@Matt:我認爲沒有「最好」的庫,因爲這項任務並不是什麼特別的。要確定哪一個最適合您的情況,我們需要更多關於您的需求的信息(例如,它應該跨平臺,交互式,集成到GUI中,...)。我可能會採用SVG的方式,但那只是我。 – nikow 2009-11-05 16:14:32

4

matplotlib這裏不是合適的庫,因爲它不是一個通用的圖形庫。這裏需要的是Cairo之類的東西,或者更簡單些,你可以使用任何GUI工具包的圖形功能,比如PyQt。另一個可行的方法是PyGame,它也具有良好的繪圖功能。

如果你想要一個例子,請看這個Cairo samples頁面的第一個示例 - arc。您只需編寫文本字,然後使用圓弧代碼爲它們之間的任何寬度和顏色的弧線。

+0

+1:開羅是一個很好的工具。 – tom10 2009-11-06 16:13:29