2017-07-20 107 views
2

我需要使用cartopy生成地图并在其上绘制一些数据(使用networkx)。我能够做到这一点,但networkx对象在地图的后面。我试图强制使用zorder图层的顺序,但是...它不工作:(cartopy + networkx:zorder不起作用

我唯一的想法是为cartopy几何图形添加一些透明度,但它看起来并不好看...... (在这个例子中它看起来并不那么糟糕,但我的整个数据,它看起来可怕)

如何强制订购任何ideias

这里是我的代码:?

import cartopy.crs as ccrs 
from cartopy.io import shapereader as shpreader 
import matplotlib.pyplot as plt 
import networkx as nx 

paises = ['Portugal', 'France', 'Canada', 'Brazil', 'Kazakhstan'] 
cidades = ['Aveiro', 'Ust-Kamenogorsk', 'Manaus'] 
links = [('Aveiro', 'Ust-Kamenogorsk'), 
     ('Manaus', 'Ust-Kamenogorsk'), 
     ('Aveiro', 'Manaus')] 
position = {'Aveiro': (-8.65, 40.6), 
      'Manaus': (-60.0, -3.1), 
      'Ust-Kamenogorsk': (82.6, 49.97)} 

# map using cartopy: 
shapename = 'admin_0_countries' 
countries_shp = shpreader.natural_earth(resolution='110m', 
            category='cultural', name=shapename) 

ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=0.0, globe=None)) 
ax.set_global() 

for country in shpreader.Reader(countries_shp).records():  
    nome = country.attributes['name_long'] 
    if nome in paises: 
     i = paises.index(nome) 
     artist = ax.add_geometries(country.geometry, ccrs.PlateCarree(), 
          facecolor='yellow', 
          #alpha=0.5, 
          zorder=10) 
    else: 
     artist = ax.add_geometries(country.geometry, ccrs.PlateCarree(), 
          facecolor='0.9', 
          zorder=10) 

# add some data over the cartopy map (using networkx):        
G = nx.Graph() 
G.add_nodes_from(cidades) 
G.add_edges_from(links) 

nx.draw_networkx_nodes(G, position, node_size=20, nodelist=cidades, zorder=20) 
edges=nx.draw_networkx_edges(G, position, edgelist=links, zorder=20) 

plt.show() 

这是我得到的图像:zorder not working with networkx over cartopy

回答

4

发生了什么事是您的zorder=20不做任何事情;它会被忽略,你可以在他们的源代码中看到。什么their draw_networkx_edges codenetworkx做的是:

def draw_networkx_edges(G, pos, 
    ... 
    edge_collection.set_zorder(1) # edges go behind nodes 
    ... 

their draw_networkx_nodes code是:

def draw_networkx_nodes(G, pos, 
    ... 
    node_collection.set_zorder(2) 
    ... 

现在,解决办法很简单:

  • 如果您在add_geometries设置zorder1,节点会再在地图前面,因为它是zorder 2.但边缘仍然在地图的后面,因为它是zorder 1.
  • 现在真正的更好的解决方案是让这两个node_collection和edge_collection第一:如果您设置的的ZORDER

    nodes.set_zorder(20) 
    edges.set_zorder(20) 
    
+0

完美!谢谢...下次我应该在源代码中寻找答案:) – carla

2

nodes = nx.draw_networkx_nodes(G, position, node_size=20, nodelist=cidades) 
edges = nx.draw_networkx_edges(G, position, edgelist=links) 

然后set_zorder这两个节点和边缘你添加到地图的形状为0,一切都按预期工作。

ax.add_geometries(..., zorder=0) 

enter image description here