Cartopy coastlines hidden by inset_axes use of Axes.pie

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-24 07:04:25

问题


I am producing a map of the world with pie charts in individual model grid boxes. I make the map and coastlines using cartopy. The pie charts I produce using inset_axes. Unfortunately the pie charts hide the coastlines and I'd like to see them clearly.

Minimum working example:

import cartopy.crs as ccrs
import numpy as np
import cartopy.feature as feature
import matplotlib.pyplot as plt

def plot_pie_inset(dataframe_pie,ilat_pie,ilon_pie,axis_main,width_local,alpha_local):
    ax_sub= inset_axes(axis_main, width=width_local, height=width_local, loc=3, bbox_to_anchor=(ilat_pie, ilon_pie),bbox_transform=axis_main.figure.transFigure, borderpad=0.0)
    wedges,texts= ax_sub.pie(dataframe_pie,colors=colors_dual)
    for w in wedges:
        w.set_linewidth(0.02)
        w.set_alpha(alpha_local)
        w.set_zorder(1)
    plt.axis('equal')

colors_dual=['RosyBrown','LightBlue']
lat_list= np.arange(0.2,0.7,0.05)

fig= plt.figure()
ax_main= plt.subplot(1,1,1,projection=ccrs.PlateCarree())
ax_main.coastlines(zorder=3)
for ilat in np.arange(len(lat_list)):
    plot_pie_inset([75,25],lat_list[ilat],0.72,ax_main,0.2,0.9)

plt.show()

I can see the coastlines by making the pie charts partially transparent by reducing the alpha value. However, this makes the colors somewhat muted. My aim is to have the coastlines as the topmost layer.

I have attempted to use 'zorder' to force the coastlines to the top layer. However, 'zorder' cannot be passed to inset_axes, nor to ax.pie so I've made the patches of color in pie charts translucent. This fails because the ax_main.coastlines does not have its own 'zorder'. The coastline zorder seems to be tied to that of ax_main. There is no benefit in increasing the zorder of ax_main.

Any suggestions greatly welcomed.


回答1:


The problem is that each axes either lies on top or below another axes. So changing the zorder of artists within axes, does not help here. In principle, one could set the zorder of the axes themselves, putting the inset axes behind the main axes.

ax_sub.set_zorder(axis_main.get_zorder()-1)

Cartopy's GeoAxes uses its own background patch. This would then need to be set to invisble.

ax_main.background_patch.set_visible(False)

Complete example:

import cartopy.crs as ccrs
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

def plot_pie_inset(dataframe_pie,ilat_pie,ilon_pie,axis_main,width_local,alpha_local):
    ax_sub= inset_axes(axis_main, width=width_local, height=width_local, loc=3, 
                       bbox_to_anchor=(ilat_pie, ilon_pie),
                       bbox_transform=axis_main.transAxes, 
                       borderpad=0.0)
    wedges,texts= ax_sub.pie(dataframe_pie,colors=colors_dual)
    for w in wedges:
        w.set_linewidth(0.02)
        w.set_alpha(alpha_local)
        w.set_zorder(1)
    plt.axis('equal')
    # Put insets behind main axes
    ax_sub.set_zorder(axis_main.get_zorder()-1)

colors_dual=['RosyBrown','LightBlue']
lat_list= np.arange(0.2,0.7,0.05)

fig= plt.figure()
ax_main= plt.subplot(1,1,1,projection=ccrs.PlateCarree())
ax_main.coastlines()

# set background patch invisible, such that axes becomes transparent
# since the GeoAxes from cartopy uses a different patch as background
# the following does not work
# ax_main.patch.set_visible(False)
# so we need to set the GeoAxes' background_patch invisible
ax_main.background_patch.set_visible(False)

for ilat in np.arange(len(lat_list)):
    plot_pie_inset([75,25],lat_list[ilat],0.72,ax_main,0.2,0.9)

plt.show()




回答2:


An alternative solution suggest by a colleague neglects to use the inset_axes but achieves a similar result. The main difference is that the coordinate system in this solution is in the original latitude/longitude coordinates rather than figure coordinates.

def plot_pie_direct(dataframe_pie,ilat_pie,ilon_pie,axis_main,width_local,alpha_local):
    wedges,texts= ax_main.pie(dataframe_pie,colors=colors_aer_atm,radius=width_local)
    for w in wedges:
        w.set_linewidth(0.02)  ## Reduce linewidth to near-zero
        w.set_center((ilat_pie,ilon_pie))
        w.set_zorder(0)

fig= plt.figure()
ax_main= plt.axes(projection=ccrs.PlateCarree())
ax_main.coastlines(zorder=3)
ax_main.set_global()
lim_x= ax_main.get_xlim()
lim_y= ax_main.get_ylim()
for ilat in np.arange(len(lat_list_trim)):
    plot_pie_direct(frac_aer_atm_reshape_trim[:,ilat,ilon],x_val_pies[ilon],y_val_pies[ilat],ax_main,lat_list_diff_trim,0.9)

ax_main.coastlines(zorder=3)
ax_main.set_xlim(lim_x)
ax_main.set_ylim(lim_y)
plt.show()


来源:https://stackoverflow.com/questions/44200931/cartopy-coastlines-hidden-by-inset-axes-use-of-axes-pie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!