修复在使用plt.xscale('symlog') 时出现的绘图伪影
如何修复 norm_pan 与 norm_tau 曲线中的这些拐点?在定义 t 时,我尝试使用相当高的分辨率和对数间距,但这并没有解决问题。
import numpy as np
import matplotlib.pyplot as plt
t = np.logspace(0, 4, 10**5, base=10)
CP = 400
P_an = 1100
tau = 30
P = CP+P_an/(1+t/tau)
dP_dPan = 1/(1+t/tau)
dP_dtau = (P_an*t)/(tau**2*(1+t/tau)**2)
S_CP = CP/P
norm_pan = (dP_dPan - dP_dPan.min()) / (dP_dPan.max() - dP_dPan.min())
norm_tau = (dP_dtau - dP_dtau.min()) / (dP_dtau.max() - dP_dtau.min())
plt.figure(figsize=(6,4))
plt.plot(t, norm_pan, label=r'$\text{P}_\text{an}$')
plt.plot(t, norm_tau, label=r'$\tau$')
plt.plot(t, S_CP, label="CP")
plt.vlines(tau, 0, max(norm_tau), linestyles=':', colors="dimgray", alpha=.4, lw=1.5)
plt.xscale('symlog')
plt.xlim(1, 10001)
plt.ylim(0, 1.05)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.set_xticks([1, 10, tau, 100, 1000, 10000])
ax.set_xticklabels([1, 10, r'$\tau$', 100, 1000, 10000])
plt.legend(fontsize=9, frameon=False, loc='center right')
plt.tight_layout()
plt.show()
我认为这是一种绘图伪影,当绘制区间 plt.xlim(0.1, 100001) 时,这种伪影会变得更加明显。
编辑
问题的解决让我意识到,关于 CP 也很可能出现了伪影;不过由于曲线在接近1 处的斜率,这一点更难观察到。
解决方案
你可以简单地把 plt.xscale('symlog') 改为 plt.xscale('log')。'symlog' 是对负值使用的 'log' 刻度的扩展,在这里你并不需要。自然地,这种扩展并非无缝,且需要移除低于一个较小阈值的数值。这正是导致你在这里遇到问题的原因。
如果你需要从0.1开始绘制,请在开头将 t 改为相应的值。
完整代码:
import numpy as np
import matplotlib.pyplot as plt
t = np.logspace(-1, 4, 100)
CP = 400
P_an = 1100
tau = 30
P = CP+P_an/(1+t/tau)
dP_dPan = 1/(1+t/tau)
dP_dtau = (P_an*t)/(tau**2*(1+t/tau)**2)
S_CP = CP/P
norm_pan = (dP_dPan - dP_dPan.min()) / (dP_dPan.max() - dP_dPan.min())
norm_tau = (dP_dtau - dP_dtau.min()) / (dP_dtau.max() - dP_dtau.min())
plt.figure(figsize=(6,4))
plt.plot(t, norm_pan, label=r'$\text{P}_\text{an}$')
plt.plot(t, norm_tau, label=r'$\tau$')
plt.plot(t, S_CP, label="CP")
plt.vlines(tau, 0, max(norm_tau), linestyles=':', colors="dimgray", alpha=.4, lw=1.5)
plt.xscale('log')
plt.xlim(0.1, 10001)
plt.ylim(0, 1.05)
ax = plt.gca()
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.set_xticks([1, 10, tau, 100, 1000, 10000])
ax.set_xticklabels([1, 10, r'$\tau$', 100, 1000, 10000])
plt.legend(fontsize=9, frameon=False, loc='center right')
plt.tight_layout()
plt.show()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。
