在matplotlib中填充两个函数之间的空间:难看的补丁
我想在两个预定义的函数之间填充一些空间,也就是:
def stravinska_SII(log_SII_Ha, eps=0):
strav_SII = 1.2 + eps + 0.61 / (log_SII_Ha - eps + 0.2)
strav_SII[log_SII_Ha > eps + 0.05] = -2
return strav_SII
和
def log_OIII_Hb_SII(log_SII_Ha, eps=0):
return 1.30 + eps + 0.72 / (log_SII_Ha - eps - 0.32)
不过,在我调整了 np.linspace
以给函数设置合适的边界(因为它的值会无限增大到 y = +∞)之后,现在有一个区域还是没有被填满。我想问问大家有没有什么新方法可以用来填补这个空白区域……?
这里有一张我称之为“空白区域问题”的图片:
注意:我希望能定义一个函数,比如在 -0.2 到 0.06 之间的 y = 1.5 的水平线,然后用它来填充这个区域(因为 axhline 有点麻烦,因为它使用了缩放关系……)
我问题的完整图示是:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib import pyplot as plt
SII = np.linspace(-3.0, 0.20)
SIIs = np.linspace(-3.0,-0.38)
def log_OIII_Hb_SII(log_SII_Ha, eps=0):
return 1.30 + eps + 0.72 / (log_SII_Ha - eps - 0.32)
def stravinska_SII(log_SII_Ha, eps=0):
strav_SII = 1.2 + eps + 0.61 / (log_SII_Ha - eps + 0.2)
strav_SII[log_SII_Ha > eps + 0.05] = -2
return strav_SII
fig = plt.figure()
gs_left = gridspec.GridSpec(1, 1)
ax = fig.add_subplot(gs_left[0,0])
ax.plot(SII, log_OIII_Hb_SII(SII), '-k')
ax.plot(SII, log_OIII_Hb_SII(SII, 0.1), '--k')
ax.plot(SII, log_OIII_Hb_SII(SII, -0.1), '--k')
ax.plot(SIIs, stravinska_SII(SIIs), '-.k')
ax.set_xlim(-2.0, 1.0)
ax.set_ylim(-1.5, 2.5)
ax.fill_between(SII, log_OIII_Hb_SII(SII), stravinska_SII(SII), where=log_OIII_Hb_SII(SII)>=stravinska_SII(SII),
facecolor='gray', alpha=0.45, edgecolor='none')
plt.show()
3 个回答
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,尤其是当我们不太了解这些工具的工作原理时。
比如说,当你在写代码的时候,可能会发现某个功能没有按照预期工作。这时候,你可以去一些技术论坛,比如StackOverflow,去寻找答案。在这些地方,很多人会分享他们的经验和解决方案。
有时候,问题的解决方案可能涉及到一些代码示例,这些示例可以帮助你更好地理解如何修复问题。记住,遇到问题是学习的一部分,不要气馁,慢慢来,总会找到解决办法的。
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib import pyplot as plt
SII = np.linspace(-3.0, 0.20)
SIIs = np.linspace(-3.0,-0.38)
Y2 = np.linspace(-0.2575, 0.06)
def log_OIII_Hb_SII(log_SII_Ha, eps=0):
return 1.30 + eps + 0.72 / (log_SII_Ha - eps - 0.32)
def stravinska_SII(log_SII_Ha, eps=0):
strav_SII = 1.2 + eps + 0.61 / (log_SII_Ha - eps + 0.2)
strav_SII[log_SII_Ha > eps + 0.05] = -2
return strav_SII
def y(x):
y = (x**2) - 1.682687002
return y
fig = plt.figure()
gs_left = gridspec.GridSpec(1, 1)
ax = fig.add_subplot(gs_left[0,0])
ax.plot(SII, log_OIII_Hb_SII(SII), '-k')
ax.plot(SII, log_OIII_Hb_SII(SII, 0.1), '--k')
ax.plot(SII, log_OIII_Hb_SII(SII, -0.1), '--k')
ax.plot(SIIs, stravinska_SII(SIIs), '-.k')
ax.plot(Y2, y(Y2), ':k')
ax.set_xlim(-2.0, 1.0)
ax.set_ylim(-1.5, 2.5)
ax.fill_between(SII, log_OIII_Hb_SII(SII), stravinska_SII(SII), where=log_OIII_Hb_SII(SII)>=stravinska_SII(SII),
facecolor='gray', alpha=0.45, edgecolor='none')
ax.fill_between(Y2, y(Y2), log_OIII_Hb_SII(Y2),
facecolor='gray', alpha=0.45, edgecolor='none')
plt.show()
stravinska_SII
在 x=-0.2 这个位置有一个渐近线。Matplotlib(一个绘图工具)正在尝试在 x 大于 -0.2 的地方填充线的上方。你正在使用 fill_between
的 where=
参数来隐藏这个填充。
你需要要么修改你的函数 stravinska_SII
,让它在 x=-0.2 以上不产生很大的正数,要么接受在这条线的上方填充是合适的这个事实。
fill_between
这个功能在处理连续的数据时效果很好,特别是当X轴的数据表现得很好的时候。如果数据不太好,那你可能需要考虑其他的方法。
一种方法是手动创建一个多边形。这个多边形会有以下的边:
- 第一个限制曲线上的点
- 第二个限制曲线上的点
这个方法的好处是你不需要考虑X和Y的限制,甚至可以使用参数曲线,如果你愿意的话。
应用到你的简单例子中:
# create the limiting polygon
vert_x = np.concatenate((SII, SIIs[::-1]))
vert_y = np.concatenate((log_OIII_Hb_SII(SII), stravinska_SII(SIIs[::-1])))
p = plt.Polygon(np.column_stack((vert_x, vert_y)), facecolor='gray', alpha=.45, edgecolor='none')
ax.add_artist(p)
这样你的例子就变成了: