【问题标题】:Scatter points on subplot edge within Gridspec get clippedGridspec 中子图边缘上的散点被剪裁
【发布时间】:2020-02-14 17:32:13
【问题描述】:

如果我像这样定义一个 Gridspec:

import matplotlib.gridspec as grd
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(15,8))
gs = grd.GridSpec(2, 1, wspace=0, hspace=0, height_ratios=[0.5, 0.5])

first = plt.subplot(gs[0])
second = plt.subplot(gs[1])

first.set_ylim(5, 10)
first.set_xlim(0, 10)
second.set_ylim(0, 5)
second.set_xlim(0, 10)

然后在共享边界的子图之一的边缘绘制一个点,

first.scatter(5, 5)
plt.show()

该点在边框上被剪裁,仅显示散点圆的上半部分。有没有办法让这个点出现在边界上? (添加clip_on=False 不会影响结果)。

部分解决方案是设置second.patch.set_alpha(0),使散点的后半部分出现。这个问题是在我的原始情节中,每个子情节都有一个背景颜色设置为

second.axhspan(*second.get_ylim(), facecolor='red', alpha=0.5)

因此,即使我使用second.patch.set_alpha(0) 将轴背景设置为透明,重叠的散点现在将有一半被 0.5 alpha 颜色覆盖,这是我不想要的。简而言之,我希望散点的 zorder 高于其他任何东西,包括周围的子图。

我想到的唯一其他解决方案(如果真的没有简单的方法来做到这一点),就是在整个图形上覆盖一个透明轴,并在那里绘制我的散点。我不想这样做的原因是因为实际上,我的 Gridspec 非常复杂,并且结合了几个非线性 y 轴,因此将点从绝对坐标映射到相对图形坐标将非常困难。

【问题讨论】:

  • 没有答案,但有一个提示:您的上 x 轴的比例在 y 轴上干扰了一半0。也许你会用fig, axs = plt.subplots(2, sharex=True, figsize=(15,8), gridspec_kw={'wspace': 0, 'hspace': 0}) 做得更好。
  • @SpghttCd 感谢您的评论。就像我在帖子中提到的那样,我的实际情节要复杂得多,我完全了解并已经解释/修复了所有重叠的特征。我没有在我发布的 sn-p 中这样做,因为它与我的问题无关,我想发布尽可能少的代码来重现我的情况。
  • Zorder 仅适用于您正在绘制的轴。您可以通过按您想要的顺序将它们添加到图形来确定将要绘制的顺序轴。但是,如果您有两个轴,并且希望最后绘制其中任何一个的未剪裁标记,我认为这是不可能的。
  • 好的,那么没有办法做到这一点吗?我想我可以定义自己的自定义比例并取消子图,但是关于定义自定义 y 比例的文档很少
  • @JodyKlymak 我怀疑这个想法是创建一个由两个或多个(线性?)范围组成的图,但每个范围都有不同的比例,例如下子图从 0 到 5,上子图从 5 到 100。出现在某个范围边缘的点不应被剪裁。

标签: python matplotlib


【解决方案1】:

这样的?

import numpy as np
import matplotlib.pyplot as plt

def forward(a):
    x = a
    ind = np.where(a>5)[0]
    x[ind] = (x[ind] - 5)*5/95 + 5
    return x


def inverse(a):
    x = a
    ind = np.where(a>5)[0]
    x[ind] = (x[ind] - 5) * 95 / 5 + 5
    return x

fig, ax = plt.subplots()

t = np.arange(0, 10, 0.01)
x = t * 10

ax.plot(t, x, 'd', ms=3)

ax.set_yscale('function', functions=(forward, inverse))
ax.set_xlim([0, 10])
ax.set_ylim([0, 100])
ax.set_yticks([0, 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])

plt.show()

【讨论】:

  • 该死的,这真是太好了。这也是我的第一次尝试(使用正向和反向函数),但我的函数太复杂了,无法计算逆。不过谢谢你,我会保存这个以供将来参考!
  • 懒惰的方法是创建一个大查找表并在正反函数中进行插值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-21
  • 2020-07-09
  • 2021-12-24
  • 2016-05-19
  • 1970-01-01
相关资源
最近更新 更多