【问题标题】:2nd scale with ticks being a function of first ticks at same position in python/matplotlib刻度的第二个刻度是 python/matplotlib 中相同位置的第一个刻度的函数
【发布时间】:2021-09-10 17:03:10
【问题描述】:

我在 Python 中使用 matplotlib,希望使用相同的绘图,但有几个不同的轴,它们都是第一个的函数,但不线性依赖于第一个 y 值。

作为示例,让我们假设一个显示简单线 y=x 的图。 现在我有一个随机函数,比如 f(y)=5y^2 + 2。

我的理想输出图现在应该还是一条线,但是等距刻度不应该是 y=1, 2, 3, 4,而是 f(y)=7, 22, 47, 82,这样我就可以叠加具有 2 个不同轴的两个图。

这是否可能,因为刻度之间的距离不均匀,也不能用对数图表示?因此,我只想在每个刻度值上放置一个函数,而不更改图形或刻度的位置。

在图形程序中,这很简单,只需使用相同的绘图并手动重写每个刻度。

https://drive.google.com/file/d/1fp2vrFvlz-9xdJPmqdQjyMQK7gzPX24G/view?usp=sharing

提前感谢您!示例代码并没有真正的帮助,因为它只是标准的 matplotlib 代码,但缺少最重要的缩放部分。 我知道我可以使用 yticks 手动设置刻度,但这并不能解决缩放问题,并且所有刻度会显得非常接近。

    plt.plot(["time_max_axis"], ["position_max_axis"])
    plt.xlabel("Time (ms)")
    plt.ylabel("Max position (mm)")
    plt.ylim(0, z0_mm)
    plt.show()

    plt.plot(["time_max_axis"], ["frequency_axis"])
    plt.xlabel("Oscillation frequency (kHz)")
    plt.ylabel("Max position (mm)")
    plt.ylim(fion_kHz, fion_kHz * (1 + (f_shift4 + f_shift6) / 100))
    plt.show()

【问题讨论】:

  • 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。
  • 据我了解,使用幽灵轴可以轻松完成。但我需要知道您的预期输出到底是什么样的。上传您想要的情节的图片(或图片链接)。
  • 作为新会员,无法上传图片,理解起来比较复杂。我改写了原来的问题!
  • 您可以发布图片链接。我看了你的编辑,还是不明白。我无法想象应该如何放置轴。每个刻度值的功能?它应该是什么意思?此外,请提供您的尝试。
  • 我会回答这个问题,但请记住,SO 不是免费编码服务的网站。你必须先尝试解决它。分享您的尝试,展示您的努力,让社区帮助您解决实际问题。您在问题中分享的那段代码与您的问题完全无关。

标签: python matplotlib


【解决方案1】:
import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)

x = np.arange(50)
y = x/10 + np.random.rand(50)

fig, axs = plt.subplots(1,2, gridspec_kw={'width_ratios': [1, 20]})
plt.subplots_adjust(wspace=0, hspace=0)

axs[1].plot(x, y)
axs[1].plot(x, 2*y)
axs[1].plot(x, 3*y)
axs[1].grid()
axs[1].set_ylim(0)
axs[1].set_xlim(0)
axs[1].set_ylabel('max displacement $z_{max}$ (mm)')

ymin, ymax = axs[1].get_ylim()
majorlocator = ymax // 8 # 8 horizontal grid lines
ytickloc = np.arange(0, int(ymax), majorlocator)
axs[1].yaxis.set_major_locator(MultipleLocator(majorlocator))

ax1 = axs[1].twinx() # ghost axis of axs[1]
ax1.yaxis.set_ticks_position('left')
ax1.set_yticks([ymin, ymax])
ax1.set_yticklabels(['', f'$z_0$ = {round(ymax,2)}'])

axs[0].spines['top'].set_visible(False)
axs[0].spines['right'].set_visible(False)
axs[0].spines['bottom'].set_visible(False)
axs[0].spines['left'].set_visible(False)
axs[0].set_xticks([])
axs[0].set_yticks(ytickloc)
ytick2 = 5 * ytickloc**2 + 2 # f = 5y^2 + 2
ytick2 = list(ytick2)
ymin2 = ytick2[0]
ytick2[0] = ''
axs[0].set_yticklabels(ytick2)
axs[0].set_ylim(ymin, ymax)
axs[0].set_ylim(0)
axs[0].set_ylabel('Oscillation frequency $f_{osc}$ (kHz)')

ymax2 = 5 * ymax**2 + 2 # f = 5y^2 + 2
ax0 = axs[0].twinx() # ghost axis of axs[0]
ax0.yaxis.set_ticks_position('left')
ax0.spines['top'].set_visible(False)
ax0.spines['right'].set_visible(False)
ax0.spines['bottom'].set_visible(False)
ax0.spines['left'].set_visible(False)
ax0.set_yticks([ymin, ymax])
ax0.set_yticklabels([f'$\\bf{{f_{{ion}}}} = {round(ymin2, 2)}$', f'$f_{{max}}$ = {round(ymax2,2)}'])

plt.tight_layout()

输出:

【讨论】:

  • yticklabels 只是文本,它与yticks 本身的位置无关。我也可以将'a', 'b', 'c' 放在那里而不是(非线性)比例。 ytickloc 本身是由这行代码中的主轴(axs[1])决定的:ytickloc = np.arange(0, int(ymax), majorlocator)
  • 非常感谢,这真的很有帮助和教益!我认为我构建的 plt 命令来自一个非常旧的版本。现在它在找到正确的导入和细微调整后工作: import matplotlib.pyplot as plt from matplotlib.ticker import MultipleLocator axs[1].set_ylim(0, z0_mm) for index, tick in enumerate(ytick2): ytick2[index] = float("{:.2f}".format(tick))
  • 我明白了,所以幽灵轴的相对刻度位置完全相同,但值是手动选择的。
  • 很高兴为您提供帮助。 plt 命令不是旧的,它只是不同的。它适用于随意绘制一个轴(这里不是这种情况)。是的,我的错,我的全部进口商品都在其他地方,不用费心去寻找它们。
  • 微调是什么意思?我的代码没有按原样工作吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
  • 2013-01-20
  • 2020-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多