在交互式matplotlib图中自动缩放y轴(带滑块)

bpzcxfmw  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(147)

我有下面的代码,它允许我交互式地更改Jupyter Notebook中的一个函数:

import numpy as np
from matplotlib.widgets import Slider, Button
import matplotlib.pyplot as plt
%matplotlib notebook

# Define stuff
my_func = lambda x, c: x - c

# Make plot
x = np.arange(0, 50, 1)
c_init = 10
fig, ax = plt.subplots()
line, = ax.plot(x, my_func(x, c_init), lw=2)

# adjust the main plot to make room for the sliders
fig.subplots_adjust(left=0.25, bottom=0.25)

# Make a vertically oriented slider to control the stock volume
ax_c = fig.add_axes([0.1, 0.25, 0.0225, 0.63])
c_slider = Slider(
    ax=ax_c,
    label="My function",
    valmin=-100,
    valmax=100,
    valinit=c_init,
    orientation="vertical"
)

# The function to be called anytime a slider's value changes
def update(val):
    line.set_ydata(my_func(x, c_slider.val))
    fig.canvas.draw_idle()
    
# register the update function with each slider
c_slider.on_changed(update)

# Create a `matplotlib.widgets.Button` to reset the sliders to initial values.
resetax = fig.add_axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', hovercolor='0.975')

def reset(event):
    c_slider.reset()
button.on_clicked(reset)

plt.show()

虽然它工作得很好,但当我改变常量时,y轴的缩放不正确。我试图使用ax.autoscale()fig.autoscale()和update函数中的一堆其他东西来修复这个问题,但它不起作用。有人知道如何做到这一点吗?
谢谢你的帮助。

c9qzyr3d

c9qzyr3d1#

滑动时,需要在ax对象上重置ylim,这意味着在update函数内部。

简单的解决方案

def update(val):
    new_ydata = my_func(x, c_slider.val)
    line.set_ydata(new_ydata)
    fig.canvas.draw_idle()
    ax.set_ylim([min(new_ydata), max(new_ydata)])

如您所见,我们定义了一个名为new_ydata的新变量,用于设置ydata,但我们也在set_ylim()函数中使用它来确定新的y轴限制。
虽然它可以工作,但它不是很好。让你的极限正好等于一个数据点在视觉上不是很吸引人。对于这个问题,我们可以引入一个容易计算的裕度。

在图中添加边距

def update(val):
    new_ydata = my_func(x, c_slider.val)
    line.set_ydata(new_ydata)
    fig.canvas.draw_idle()
    relative_margin = 0.05
    min_new_y = min(new_ydata)
    max_new_y = max(new_ydata)
    margin = (max_new_y - min_new_y)*relative_margin
    ax.set_ylim([min_new_y - margin, max_new_y + margin])

如您所见,我们的操作与之前相同,但我们引入了一个裕度,我们使用relative_margin值作为数据大小的一个比例,这样您就始终有一个随数据缩放的良好裕度。
希望这有帮助!

相关问题