Matplotlib:在等值线图之上将散点图绘制到前景

问题描述 投票:0回答:2

有人知道如何在 matplotlib 中将散点图带到前台吗?我必须在轮廓顶部显示散点图,但默认情况下它绘制在下面......

python matplotlib scatter-plot
2个回答
102
投票

您可以使用

zorder
参数手动选择不同图的显示顺序。
scatter
方法。

为了进行演示,请参阅下面的代码,其中左侧子图中的散点图具有

zorder=1
,右侧子图中的散点图具有
zorder=-1
zorder
最高的物体放置在顶部。这意味着散点图将放置在第一个子图中的等高线的顶部,而它放置在第二个子图中的下方。

import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = 10.0 * (Z2 - Z1)

norm = cm.colors.Normalize(vmax=abs(Z).max(), vmin=-abs(Z).max())
cmap = cm.PRGn

levels = np.arange(-2.0, 1.601, 0.4)

fig, axes = plt.subplots(1,2, sharey=True)

for ax, zord in zip(axes, [1, -1]):
    ax.contourf(X, Y, Z, levels,
                cmap=cm.get_cmap(cmap, len(levels)-1),
                norm=norm)
    ax.autoscale(False) # To avoid that the scatter changes limits
    ax.scatter(np.random.uniform(-3,3,10),
               np.random.uniform(-2,2,10),
               zorder=zord)
    ax.set_title('Scatter with zorder={0}'.format(zord))

enter image description here


0
投票

使用任意浮点值设置 zorder

matplotlib 图形上的所有内容都是

zorder
,您可以在 docs 中找到它们的默认值。但事实是,您甚至不需要记住默认值,因为您可以将 zorder 设置为您想要的任何数字,其中
zorder
值较高的艺术家将绘制在顶部;在显示哪个图位于哪个图之上时,只有您分配的值的ordinal排名(而不是cardinal值)才重要。

例如,在下图中,我们将

zorder
值分配给
scatter
contourf
调用。正如您所看到的,在两个子图中,具有较高 zorder 的图显示在顶部。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from scipy import stats

delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)

X, Y = np.meshgrid(x, y)
Z1 = stats.multivariate_normal([0, 0], [[1, 0], [0, 1]]).pdf(np.dstack((X, Y)))
Z2 = stats.multivariate_normal([1, 1], [[1.5, 0], [0, 0.5]]).pdf(np.dstack((X, Y)))
Z = 10.0 * (Z2 - Z1)

vmax = np.abs(Z).max()
norm = mpl.colors.Normalize(vmin=-vmax, vmax=vmax)
cmap = mpl.colormaps["PRGn"]
levels = np.arange(-2.0, 1.601, 0.4)

x = np.random.uniform(-3,3,10)
y = np.random.uniform(-2,2,10)

fig, axes = plt.subplots(1, 2, sharey=True)

for ax, zord in zip(axes, [-0.5, 0.5]):
    ax.scatter(x, y, zorder=zord)
    #                ^^^^^^^^^^^  <--- zorder here
    ax.contourf(X, Y, Z, levels, 
                norm=norm, cmap=cmap, zorder=zord*2)
    #                                 ^^^^^^^^^^^^^  <--- zorder here
    ax.autoscale(False)
    ax.set_title(f'Scatter with zorder={zord}\ncontour with zorder={zord*2}')

plots with different zorder

绘图的绘制顺序很重要

如果两位艺术家具有相同的

zorder
,则最后绘制的艺术家将显示在顶部。事实上,contour 和 scatter 都是一个 Collection,所以默认情况下,它们具有相同的
zorder
。 OP 中未显示散点图的原因是散点图是在等高线图之前绘制的。所以OP的一种解决方案是在等高线图之后绘制散点图(所以在sodd的答案中,因为散点图是最后绘制的,所以你甚至不需要设置zorder)。您可以通过以下方式确认(使用与上面相同的数据):

plt.contourf(X, Y, Z, levels, norm=norm, cmap=cmap)
plt.scatter(x, y)

order matters

使用
set_zorder()

更改 zorder

如上所述,散点图和等高线图的艺术家都存储在绘制它们的 Axes 对象的

.collections
中(并且按照绘制顺序存储在其中)。您可以使用以下代码进行确认。然后,您也可以通过调用这些对象的
zorder
来更改这些对象的
set_zorder()
。如果使用某些在后端使用 matplotlib 的第三方库创建绘图,这尤其有用。

下面的代码生成与上面相同的图形。

fig, ax = plt.subplots()
ax.scatter(x, y)
ax.contourf(X, Y, Z, levels, norm=norm, cmap=cmap)
ax.collections                 # <Axes.ArtistList of 2 collections>
scatter = ax.collections[0]    # <matplotlib.collections.PathCollection at 0x223b2519610>
contour = ax.collections[1]    # <matplotlib.contour.QuadContourSet at 0x223a69dc390>

# set zorders here
scatter.set_zorder(1)
contour.set_zorder(0.9)
© www.soinside.com 2019 - 2024. All rights reserved.