没有在底图上绘制带有 networkx 的虚线

No dotted line with networkx drawn on basemap

我尝试在 basemap 线上用 networkx 绘制虚线边。一切正常,除了 style= 'dotted'。设置此标志后,没有任何改变。我仍然得到正常的坚固边缘。有没有人知道我可以改变什么来在地图上画一条虚线?我的错误在哪里?

这是我的完整脚本:

import networkx as nx
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd
geodict={'ID': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10, 10: 11, 11: 12, 12: 13, 13: 14, 14: 15, 15: 16, 16: 17, 17: 18, 18: 19, 19: 20, 20: 21, 21: 22}, 'Name': {0: 'Bremen', 1: 'Passau', 2: 'Wolgagebiet', 3: 'Ellis Island', 4: 'Nebraska', 5: 'Berlin', 6: 'Prag', 7: 'München', 8: 'Frankfurt am Main', 9: 'Dresden', 10: 'Bresslau', 11: 'Königsberg', 12: 'Moskau', 13: 'Warschau', 14: 'Buenos Aires', 15: 'Chicago', 16: 'Philadelphia', 17: 'Cleveland', 18: 'Detroit', 19: 'Milwaukee', 20: 'Baltimore', 21: 'Rio de Janeiro'}, 'lat': {0: 53.075878, 1: 48.573333, 2: 51.7, 3: 40.698611, 4: 41.583333, 5: 52.518611, 6: 50.088611, 7: 48.137221999999994, 8: 50.110556, 9: 51.049259, 10: 51.11, 11: 54.733332999999995, 12: 55.75, 13: 52.216667, 14: -34.599722, 15: 41.881944, 16: 39.952222, 17: 41.482222, 18: 42.3316, 19: 43.052222, 20: 39.286389, 21: -22.908333}, 'lng': {0: 8.807311, 1: 13.456944, 2: 46.75, 3: -74.04, 4: -99.583333, 5: 13.408332999999999, 6: 14.421389000000001, 7: 11.575556, 8: 8.682222, 9: 13.73836, 10: 17.032222, 11: 20.483333, 12: 37.616667, 13: 21.033333, 14: -58.381944, 15: -87.627778, 16: -75.163889, 17: -81.669722, 18: -83.0475, 19: -87.955833, 20: -76.615, 21: -43.196389}, 'Anz': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0}}
geopos= pd.DataFrame.from_dict(geodict)
position={}
m = Basemap(projection='ortho',lon_0=-20,lat_0=30,resolution='l')
m.shadedrelief()

font = {'family': 'serif',
        'color':  'black',
        'weight': 'normal',
        'size': 12,
        }
for line in geopos.itertuples():
    position[line.Name] = m(line.lng, line.lat)
    if line.Anz==1:
        if line.Name=='Nebraska':
            plt.text(position[line.Name][0] - 150000, position[line.Name][1] + 100000, line.Name, font)
        elif line.Name == 'Bremen':
            plt.text(position[line.Name][0] - 250000, position[line.Name][1] - 200000, line.Name, font)
        else:
            plt.text(position[line.Name][0] - 200000, position[line.Name][1] - 180000, line.Name, font)
G=nx.DiGraph()
G2=nx.DiGraph()
G.add_node('Bremen',weight=10, label='Bremen')
G.add_node('Wolgagebiet',weight=1)
G.add_node('Passau',weight=1)
G.add_node('Ellis Island',weight=10)
G.add_node('Nebraska',weight=1)
G2.add_node('Passau',weight=1)
G2.add_node('Ellis Island',weight=10)
G2.add_node('Berlin',weight=1)
G2.add_node('Prag',weight=1)
G2.add_node('München',weight=1)
G2.add_node('Frankfurt am Main',weight=1)
G2.add_node('Dresden',weight=1)
G2.add_node('Bresslau',weight=1)
G2.add_node('Königsberg',weight=1)
G2.add_node('Moskau',weight=1)
G2.add_node('Warschau',weight=1)
G2.add_node('Buenos Aires',weight=1)
G2.add_node('Chicago',weight=1)
G2.add_node('Philadelphia',weight=1)
G2.add_node('Cleveland',weight=1)
G2.add_node('Detroit',weight=1)
G2.add_node('Milwaukee',weight=1)
G2.add_node('Baltimore',weight=1)
G2.add_node('Rio de Janeiro',weight=1)

G.add_edge('Wolgagebiet','Bremen')
G.add_edge('Passau','Bremen')
G.add_edge('Bremen','Ellis Island')
G.add_edge('Ellis Island', 'Nebraska')

G2.add_edge('Berlin','Bremen')
G2.add_edge('Prag','Bremen')
G2.add_edge('München','Bremen')
G2.add_edge('Frankfurt am Main','Bremen')
G2.add_edge('Dresden','Bremen')
G2.add_edge('Bresslau','Bremen')
G2.add_edge('Königsberg','Bremen')
G2.add_edge('Moskau','Bremen')
G2.add_edge('Warschau','Bremen')
G2.add_edge('Bremen','Buenos Aires')
G2.add_edge('Ellis Island','Chicago')
G2.add_edge('Ellis Island','Philadelphia')
G2.add_edge('Ellis Island','Cleveland')
G2.add_edge('Ellis Island','Detroit')
G2.add_edge('Ellis Island','Milwaukee')
G2.add_edge('Ellis Island','Baltimore')
G2.add_edge('Bremen','Rio de Janeiro')

pos = dict((land, position[land]) for land in G.nodes())
pos2 = dict((land, position[land]) for land in G2.nodes())
print(G.edges)
lllon = -80
urlon = 80
lllat = 20
urlat = 50

xmin, ymin = m(lllon, lllat)
xmax, ymax = m(urlon, urlat)

ax = plt.gca()

ax.set_xlim([xmin, xmax])
ax.set_ylim([ymin, ymax])

nx.draw_networkx_nodes(G2, pos2, with_labels=True,node_size=[[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]],node_color='grey')
nx.draw_networkx_edges(G2, pos2, width = 1,style='dotted',edge_color='grey')
nx.draw_networkx_nodes(G, pos, with_labels=True,node_size=[[200, 20, 20, 200, 20]],node_color='red')
nx.draw_networkx_edges(G, pos, color='white', width = [7,3,3,3,3],style='dashdot',edge_color='b')
plt.show()

我觉得这很像一个错误——也许你应该向 networkx 开发人员提出来。现在,我找到了解决方法。当调用 help(nx.draw_networkx_edges) 时,您会得到以下信息:

Returns

matplotlib.collection.LineCollection LineCollection of the edges

list of matplotlib.patches.FancyArrowPatch FancyArrowPatch instances of the directed edges

Depending whether the drawing includes arrows or not.

networkx documentation pages别提第二种可能了,btw。无论如何,当您使用箭头时,您可以检索 FancyArrowPatch 中的 list 并为这些 'by hand' 设置线条样式。简而言之,如果您像这样更改代码的最后几行:

collection = nx.draw_networkx_edges(G2, pos2, width = 2,edge_color='grey')
for patch in collection:
    patch.set_linestyle('dotted')

nx.draw_networkx_nodes(G, pos, with_labels=True,node_size=[[200, 20, 20, 200, 20]],node_color='red')

collection = nx.draw_networkx_edges(G, pos, color='white', width = [7,3,3,3,3],edge_color='b')
for patch in collection:
    patch.set_linestyle('dashdot')

plt.show()

你得到虚线:

在 python 3.6 上测试(2.7 给我一个关于字符编码的错误)。希望这有帮助。