用Python制作拱形关系信息图
这是一个非常具体的信息图表挑战,基本问题是如何使用matplotlib、cairo或其他Python库在单词之间建立弧线。
给定以下数据结构。
me, you, 7 |
me, apple, 9 |
apple, you, 1 |
bike, me, 5
名字会水平显示,关系最多的名字会比其他的更大,然后在名字之间会有加权的弧线。比如,一个权重为10的弧线会比一个权重为5的弧线粗两倍。
灵感来源于:相似多样性。 http://similardiversity.net/
让挑战开始吧!
3 个回答
0
我其实看不出有什么难点或者挑战。你只需要一个可以画文字和半圆的图形库,这在很多地方都能做到。根本不需要用到贝塞尔曲线。比如,你可以简单地创建一个SVG文件(这样你甚至不需要任何库,就可以把它很好地嵌入到网页中,并用一些JavaScript让它变得互动)。
实际的绘制过程很简单:圆心就在两个词之间的中间,半径就是它们之间距离的一半。然后你可以调整线条的粗细来表示其他的数量。
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作为后端)。它和Networkx非常相似(都是同一个主要开发者)。