matplotlib fill_between可以使用自定义转换到无穷大吗?

xtupzzrd  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(82)

有没有一种方法可以用一条曲线和无穷大之间的颜色填充图形?
我正在寻找类似ax.fill_between( x, y, 'inf' )的东西
我不想只填充到y.max()或ax.get_ylim(),因为我希望能够缩小视图并在视图中移动,同时颜色始终填充曲线的上部。
最后,我能做的最好的是下面的代码,它确实填充到无穷大,但在两个方向上都是+inf/-inf,并且只有在y>0时才有效:

import matplotlib.pyplot as plot
import numpy as np

fig, ax = plot.subplots()
x = np.arange(0, 4 * np.pi, 0.01)
y = np.sin(x)
ax.plot(x, y)

ax.fill_between(x, 0, 1, where = [True]*len(y), transform=ax.get_xaxis_transform(), color = 'blue', alpha = 0.3 )
ax.fill_between(x, 0, y, color = 'white', alpha = 1)
plot.show()

我真正需要的是使下面的代码行工作:

ax.fill_between( x, y, 1, where = [True]*len(y), transform=custom_transform )

自定义转换必须考虑数据坐标中的第二个参数y和轴坐标中的第三个参数1。
然而,我不知道这是否可能,自定义转换对我的技能水平来说有点太多了。

mpbci0fu

mpbci0fu1#

你不能把上限设为无穷大,我们需要一个实际的数字。
一种选择是你只需要将上限设置为非常大的值,当平移/缩放时,你不太可能达到这个值,例如1 e32:

ax.fill_between(x, y, 1e32)

或者,您可以在轴上使用回调函数,以便在y限制更改时执行操作;在本例中,每当绘图区域更新时,我们将更新ax.fill_between返回的PolyCollection。有几种方法可以做到这一点,但没有一种特别简单。在这里,我使用this answer的方法,其中我们绘制一个虚拟fill_between,以获得具有更新的y限制的PolyCollection的新顶点,然后更新原始PolyCollection,并删除虚拟示例。

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
x = np.arange(0, 4 * np.pi, 0.01)
y = np.sin(x)
ax.plot(x, y)

fill = ax.fill_between(x, y, 2 * y.max())
ax.set_ylim(-2, 2 * y.max())

def on_ylims_change(event_ax):
    
    # Create a dummy PolyCollection with the new y-limit,
    # to use the vertices created, then remove the dummy
    dummy = ax.fill_between(x, y, event_ax.get_ylim()[1], alpha=0)
    dpaths = dummy.get_paths()[0]
    dummy.remove()

    # Update our original PolyCollection with the new vertices
    fill.set_paths([dpaths.vertices])

ax.callbacks.connect('ylim_changed', on_ylims_change)

plt.show()

你应该能够缩放/平移/设置任何限制,填充将始终达到你的轴的顶部。
测试并与Python v3.10.12和matplotlib v3.7.2以及Python v3.11.5和matplotlib v3.8.0一起使用

owfi6suc

owfi6suc2#

您可以使用ax.get_ylim()作为限值,这将根据图中数据的范围而变化。

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
x = np.arange(0, 4 * np.pi, 0.01)
y1 = np.sin(x)
y2 = np.sin(x)-x
ax.plot(x, y1)
ax.plot(x, y2)

ax.fill_between(x, y1, ax.get_ylim()[1], color='skyblue')
ax.fill_between(x, y1, ax.get_ylim()[0], color='lightgreen')
ax.fill_between(x, y2, ax.get_ylim()[0], color='orange')

相关问题