我使用2个滑块来调整2D热图的颜色条;一个用于底部(最小),一个用于顶部(最大)。我想确保两者不能重叠,即如果整个范围是0到5并且我将最大值设置为2那么最小值不能超过2.这应该以交互方式发生。我怎样才能做到这一点?另外有没有办法将两个滑块合二为一?谢谢。
我GUI的一个例子。以及代码的相关部分:
def update(val, s=None):
"""Retreives the value from the sliders and updates the graph accordingly"""
_cmin = s_cmin.val
_cmax = s_cmax.val
pcm.set_clim([_cmin, _cmax])
plt.draw()
def reset(event):
"""Resets the sliders when the reset button is pressed"""
s_cmin.reset()
s_cmax.reset()
fig, ax = plt.subplots(figsize=(13,8))
plt.subplots_adjust(left=0.25,bottom=0.25)
# define axis minima and maxima:
x_min = Xi.min()
x_max = Xi.max()
y_min = Yi.min()
y_max = Yi.max()
c_min = Zi.min()
c_max = Zi.max()
pcm = ax.pcolormesh(Xi,Yi,Zi)
cb = plt.colorbar(pcm)
axcolor = 'lightgoldenrodyellow'
axx = plt.xlim([x_min, x_max])
ayy = plt.ylim([y_min, y_max])
# create a space in the figure to place the two sliders:
ax_cmin = plt.axes([0.15, 0.10, 0.65, 0.02], facecolor=axcolor)
ax_cmax = plt.axes([0.15, 0.15, 0.65, 0.02], facecolor=axcolor)
# the first argument is the rectangle, with values in percentage of the figure
# size: [left, bottom, width, height]
# create each slider on its corresponding place:
s_cmax = Slider(ax_cmax, 'max', c_min, c_max, valinit=c_max, valfmt='%1.4f')
s_cmin = Slider(ax_cmin, 'min', c_min, c_max, valinit=c_min, valfmt='%1.4f')
# set both sliders to call update when their value is changed:
s_cmin.on_changed(update)
s_cmax.on_changed(update)
# create a space in the figure to place the reset button
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
# create the reset button
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')
button.on_clicked(reset)
# create a space in the figure to place the textboxes:
axbox_xmin = plt.axes([0.07, 0.55, 0.04, 0.04])
axbox_xmax = plt.axes([0.12, 0.55, 0.04, 0.04])
axbox_ymin = plt.axes([0.07, 0.49, 0.04, 0.04])
axbox_ymax = plt.axes([0.12, 0.49, 0.04, 0.04])
# create the textboxes
tb_xmin = TextBox(axbox_xmin,'x', color=axcolor, hovercolor='0.975', label_pad=0.01)
tb_xmax = TextBox(axbox_xmax,'', color=axcolor, hovercolor='0.975')
tb_ymin = TextBox(axbox_ymin,'y', color=axcolor, hovercolor='0.975', label_pad=0.01)
tb_ymax = TextBox(axbox_ymax,'', color=axcolor, hovercolor='0.975')
# create the submit action
tb_xmin.on_submit(submit)
tb_xmax.on_submit(submit)
tb_ymin.on_submit(submit)
tb_ymax.on_submit(submit)
plt.show()
答案 0 :(得分:0)
在某些情况下,确实可能需要一个可以同时设置最小值和最大值的滑块。因此,滑块可以有两个值,而滑块内的矩形将由两个值限制,而不是从滑块的最小值开始,而不是只有一个值。
以下是这种情况的解决方案。它使用MinMaxSlider
,即Slider的子类,适用于托管两个值
它不是单个输入值,而是期望两个值,
MinMaxSlider(... , valinit=0.5,valinit2=0.8)
使Sliderbar的范围从0.5到0.8。单击滑块将更改更接近单击的值,从而使拖动变得相当容易。
为了使用这个滑块,请注意通过on_changed
回调的函数现在自然有两个参数。
import six
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
class MinMaxSlider(Slider):
def __init__(self,ax, label, valmin, valmax, **kwargs):
self.valinit2 = kwargs.pop("valinit2", valmax)
self.val2 = self.valinit2
Slider.__init__(self,ax, label, valmin, valmax, **kwargs)
self.poly.xy = np.array([[self.valinit,0],[self.valinit,1],
[self.valinit2,1],[self.valinit2,0]])
self.vline.set_visible(False)
def set_val(self, val):
if np.abs(val-self.val) < np.abs(val-self.val2):
self.val = val
else:
self.val2 = val
self.poly.xy = np.array([[self.val,0],[self.val,1],
[self.val2,1],[self.val2,0]])
self.valtext.set_text(self.valfmt % self.val +"\n"+self.valfmt % self.val2)
if self.drawon:
self.ax.figure.canvas.draw_idle()
if not self.eventson:
return
for cid, func in six.iteritems(self.observers):
func(self.val,self.val2)
import numpy as np
x = np.linspace(0,16,1001)
f = lambda x: np.sin(x)*np.sin(1.7*x+2)*np.sin(0.7*x+0.05)*x
fig,(ax, sliderax) = plt.subplots(nrows=2,gridspec_kw={"height_ratios":[1,0.05]})
fig.subplots_adjust(hspace=0.3)
ax.plot(x,f(x))
slider = MinMaxSlider(sliderax,"slider",x.min(),x.max(),
valinit=x.min(),valinit2=x.max())
def update(mini,maxi):
ax.set_xlim(mini,maxi)
slider.on_changed(update)
update(x.min(),x.max())
plt.show()