简体   繁体   中英

matplotlib: ordering of zoomed axes objects

I am building a figure with a primary axis that is a scatter plot and a zoomed axis which focuses on a particular region of the primary axis, both of which have gridlines. When I place the zoomed axis as an inset, it "covers" up some of the primary axis data. I want to be able to show the primary axis data ( zorder=100 ) through the zoomed axis, so I set the zoomed axis to be transparent ( alpha=0 ). Finally, I want the primary axis gridlines to "cut-off" when they meet the zoomed axis ( zorder=10 ) but I want to show the zoomed axis gridlines ( zorder=50 ). Is this possible? Below is my attempt:

import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
import numpy as np
fig = plt.figure(figsize=(10,7.5))
gs = matplotlib.gridspec.GridSpec(1, 2, width_ratios=[20,1], height_ratios=[1])
ax = plt.subplot(111)

## data
xx = np.linspace(1,100,num=100) + 20 * np.random.normal(0,1,100)
yy = np.linspace(1,100,num=100) + 10 * np.random.normal(0,1,100)

## scatter
sc = ax.scatter(xx, yy, s=250, alpha=0.35, zorder=100)
ax.plot(np.linspace(-100,200,301), np.linspace(-100,200,301),)
ax.set_xlim((0, 100))
ax.set_ylim((0, 100))
ax.grid(linestyle="--", zorder=10)

## zoom
axins = zoomed_inset_axes(ax, 2, loc="upper left")
scins = axins.scatter(xx, yy, s=100, alpha=0.35, zorder=50, marker=".", c="red")
axins.plot(np.linspace(-100,200,301), np.linspace(-100,200,301), c="red")
axins.set_xlim((70, 90))
axins.set_ylim((70, 90))
mark_inset(ax, axins, loc1=1, loc2=4, fc="none", ec="0.5")
axins.grid(linestyle="--", zorder=50)
plt.show()

在此处输入图片说明

In particular, one of the blue data points near x=80 gets cut off. I can set axins.patch.set_alpha(0.0) , but then it doesn't remove the primary grid lines.

One option is indeed to put a white patch (white rectangle) in ax at the position where axins lives and set that patches' zorder to higher than the one from the gridlines, but lower than the one from the scatter.

# Set axins' background patch invisible
axins.patch.set_visible(False)
# Create a new patch at the position of the axins axes.
rect = matplotlib.patches.Rectangle((0,0), 1,1,
          fill=True, facecolor="white", edgecolor="red",zorder=25,
          transform=axins.transAxes)
ax.add_patch(rect)

Thanks to @ImportanceOfBeingErnest for the suggestion. It works to add a rectangle with an intermediate zorder to ax per the following (where I've left the red outline of the rectangle):

import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
import matplotlib.patches as patches
import numpy as np

## data
xx = np.linspace(1,100,num=100) + 20 * np.random.normal(0,1,100)
yy = np.linspace(1,100,num=100) + 10 * np.random.normal(0,1,100)

## fig
fig = plt.figure(figsize=(10,7.5))
gs = matplotlib.gridspec.GridSpec(1, 2, width_ratios=[20,1], height_ratios=[1])
ax = plt.subplot(111)

## scatter
sc = ax.scatter(xx, yy, s=250, alpha=0.35, zorder=100)
ax.plot(np.linspace(-100,200,301), np.linspace(-100,200,301))
ax.set_xlim((0, 100))
ax.set_ylim((0, 100))
ax.grid(linestyle="--", zorder=10)
ax.patches.extend([patches.Rectangle((0.2, 0.6), 0.4, 0.4,
                                  fill=True, facecolor="white", edgecolor="red",zorder=25,
                                  transform=ax.transAxes, figure=ax)])

## zoom
axins = zoomed_inset_axes(ax, 2,
                          bbox_to_anchor=(0.6, 1.0, 0.0, 0.0),
                          bbox_transform=ax.transAxes)
scins = axins.scatter(xx, yy, s=100, alpha=0.35, zorder=50, marker=".", c="red")
axins.plot(np.linspace(-100,200,301), np.linspace(-100,200,301), c="red")
axins.set_xlim((70, 90))
axins.set_ylim((70, 90))
axins.patch.set_alpha(0.0)
mark_inset(ax, axins, loc1=1, loc2=4, fc="none", ec="0.5")
axins.grid(linestyle="--", zorder=50)
plt.show()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM