這篇文章實現的算法來源於PNAS雜誌:
PNAS paper:From time series to complex networks:The visibility graph
代碼參考:
# coding: utf-8
import networkx as nx
import matplotlib.pyplot as plt
from itertools import combinations
def visibility_graph(series):
visibility_graph_edges=[]
# convert list of magnitudes into list of tuples that hold the index
tseries = []
n = 1
for magnitude in series:
tseries.append( (n, magnitude ) )
n += 1
for a,b in combinations(tseries, 2):
# two points, maybe connect
(ta, ya) = a #實現(1,2)(1,3)(1,4)(1,5)--(2,3)(2,4)(2,5)--(3,4)(3,5)--(4,5)任意兩個邊相互比較
(tb, yb) = b
connect = True
medium=tseries[ta:tb-1]#此處需要多留意,ta是1到k,而tseris是從0下標開始 所以此處不能不是[ta+1:tb]
for tc,yc in medium:
#print yc,(yb + (ya - yb) * ( float(tb - tc) / (tb - ta) ))#一定要float(tb-tc)/(tb-ta)因爲計算機裏1/2爲0,1.0/2才爲0.5
if yc > yb + (ya - yb) * ( float(tb - tc) / (tb - ta) ):
connect =False
if connect:
visibility_graph_edges.append((ta,tb))
return visibility_graph_edges
def DrawVisibilityGraph(graphEdges):
G=nx.Graph() #G=nx.Graph()無向圖 G=nx.DiGraph()有向圖
#add the edge to graph G
for i in graphEdges:
G.add_edge(i[0],i[1])
pos=nx.spring_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=700)
nx.draw_networkx_edges(G,pos,width=5)
nx.draw_networkx_labels(G,pos,font_size=20,font_family='sans-serif')
#plt.savefig("test.png") #save the picture
plt.show()
if __name__=="__main__":
#time series
series = [0.87,0.49,0.36,0.83,0.87]
#get the graph edges
graphEdges=visibility_graph(series)
#draw the visibility graph
DrawVisibilityGraph(graphEdges)
代碼運行結果:
繪圖參考鏈接:
http://networkx.github.io/documentation/latest/examples/drawing/weighted_graph.html