2017-05-26 2 views
1

Je produis une carte du monde avec des camemberts dans des boîtes de maquettes individuelles. Je fais la carte et les côtes en utilisant cartopy. Les camemberts que je produis en utilisant inset_axes. Malheureusement, les camemberts cachent les côtes et j'aimerais les voir clairement.Côtes littorales cachées par l'utilisation d'inset_axes de Axes.pie

exemple de travail minimum:

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

je peux voir les côtes en faisant les camemberts partiellement transparents en réduisant la valeur alpha. Cependant, cela rend les couleurs légèrement atténuées. Mon but est d'avoir les côtes comme couche supérieure.

J'ai essayé d'utiliser 'Zorder' pour forcer les côtes à la couche supérieure. Cependant, 'zorder' ne peut pas être passé à inset_axes, ni à ax.pie donc j'ai rendu translucides les taches de couleur dans les camemberts. Cela échoue car ax_main.coastlines n'a pas son propre 'zorder'. Le littoral semble être lié à celui de ax_main. Il n'y a aucun avantage à augmenter le zorder de ax_main.

Toutes les suggestions sont les bienvenues.

Répondre

2

Le problème est que chaque axe se trouve sur le dessus ou sous un autre axe. Donc, changer le zorder des artistes dans les axes, n'aide pas ici. En principe, on pourrait définir la zordie des axes eux-mêmes, en plaçant les axes encastrés derrière les axes principaux.

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

GeoAxes de Cartopy utilise son propre correctif d'arrière-plan. Cela devrait alors être défini sur invisble.

ax_main.background_patch.set_visible(False) 

Exemple complet:

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

enter image description here

+0

Merci beaucoup pour la réponse rapide et utile. – LeightonRegayre

+0

Il n'est pas clair pour moi comment le fait de rendre le patch d'arrière-plan invisible permet aux littoraux d'être visibles. Est-ce que set_visible (False) tel qu'utilisé travaille à la fois sur l'arrière-plan de GeoAxes et sur les côtes, ou seulement sur l'arrière-plan? Je suppose qu'il y a une différence subtile entre visible et partiellement transparent qui signifie que l'invisible permet de voir les lignes des côtes. Est-ce exact? Merci encore! – LeightonRegayre

+1

Le fond est un rectangle blanc derrière tout dans les axes (donc aussi derrière les côtes). Si nous plaçons les encarts derrière les axes principaux, ce rectangle blanc est devant les encarts et les cache. Mais rendre l'arrière-plan invisible (c'est-à-dire tuer le rectangle blanc) permet de voir tout ce qui se trouve derrière les axes principaux. – ImportanceOfBeingErnest

1

Une solution alternative suggère par un collègue néglige d'utiliser les inset_axes mais permet d'obtenir un résultat similaire. La principale différence est que le système de coordonnées de cette solution est dans les coordonnées de latitude/longitude d'origine plutôt que dans les coordonnées de figure.

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