【问题标题】:cartopy + networkx: zorder is not workingcartopy + networkx:zorder 不工作
【发布时间】:2017-12-25 11:18:12
【问题描述】:

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

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

关于如何强制命令的任何想法?

这是我的代码:

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()

这是我得到的图像:

【问题讨论】:

    标签: python matplotlib networkx z-order cartopy


    【解决方案1】:

    发生的事情是您的zorder=20 没有做任何事情;正如您在他们的源代码中看到的那样,它被忽略了。 networkxtheir draw_networkx_edges code 中所做的是:

    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 中的zorder 设置为1,则节点将位于地图前面,因为它是zorder 2。但边仍然在地图后面,因为它是zorder 1。
    • 现在真正更好的解决方案是先获取 node_collection 和 edge_collection:

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

      然后set_zorder 用于节点和边:

      nodes.set_zorder(20)
      edges.set_zorder(20)
      

    【讨论】:

    • 完美!谢谢...下次我应该在源代码中寻找答案:)
    【解决方案2】:

    如果您将添加到地图的形状的 zorder 设置为 0,则一切都会按预期进行。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 2016-05-30
      • 2017-05-06
      • 1970-01-01
      • 2021-01-10
      相关资源
      最近更新 更多