2017-04-14 39 views
1

在與matplotlib.widgets.Slider實例關聯的回調函數中,我想修改滑塊valminvalmaxval屬性,然後重新繪製Slider。當我嘗試重新繪製它時,沒有任何反應。如何在更改某些小部件的屬性後強制重繪小部件?

在回撥完成之前,我打電話plt.draw(),而當其餘的圖被正確更新時,Slider看起來與以前相同。我也嘗試撥打SliderAxes上的draw(),並且再次沒有明顯的變化。

如何在更改其屬性後強制重新繪製Slider實例?

Thansk!

UPDATE

這裏的一個小程序,演示了這個問題(與粗對話)。想要的行爲是通過單擊單選按鈕的不同值,滑塊更改值的範圍,當前值和標籤。反而會發生什麼情況是,當點擊「漸變」時,滑塊停止響應(不能再拖動),並且當單擊「漸變」或「通道」時,滑塊不會更新,儘管調用了plt.draw()

from matplotlib import pyplot as plt 
from matplotlib import gridspec 
from matplotlib.widgets import Slider, RadioButtons 

# Set the grid 
grid = gridspec.GridSpec(2, 1, height_ratios=[1, 2]) 

# Plot the sliders 
axes_slider = plt.subplot(grid[0, 0]) 
slider = Slider(axes_slider, 'Channel', valmin=0, valmax=255, valinit=128) 

# Plot the radio buttons 
axes_button = plt.subplot(grid[1, 0]) 
button = RadioButtons(axes_button, ('Gradient', 'Channel'), active=1) 

plt.tight_layout(h_pad=0) 
plt.subplots_adjust(left=.2, right=.9) 

def update(_): 
    take_gradient = True if button.value_selected == 'Gradient' else False 
    if take_gradient: 
     slider.valmin = -1 
     slider.valmax = 1 
     slider.val = 0 
     slider.label= 'Gradient' 
     slider.valinit = 0 
    else: 
     slider.valmin = 0 
     slider.valmax = 255 
     slider.val = 128 
     slider.label = 'Channel' 
     slider.valinit = 128 
    plt.draw() 

# Register call-backs with widgets 
slider.on_changed(update) 
button.on_clicked(update) 

plt.show() 
+0

我會盡量拿出一個短節目仍然重現問題。 – Fanta

+0

我用代碼示例更新了問題。 – Fanta

回答

1

滑塊本身是一個承載和管理一些參數的類。它沒有繪製方法。

也就是說,僅設置滑塊的參數是不夠的,您還需要更新滑塊所在的軸。最後,這些總結了完成滑塊正在執行初始化的步驟,所以你可以簡單地調用silder的__init__函數。

我強烈建議使用兩個不同的函數,一個用於更改在按鈕單擊時調用的滑塊,另一個用於調整滑塊值時發生的事情。

這裏是一個工作示例:

from matplotlib import pyplot as plt 
from matplotlib import gridspec 
from matplotlib.widgets import Slider, RadioButtons 

# Set the grid 
grid = gridspec.GridSpec(2, 1, height_ratios=[1, 2]) 

# Plot the sliders 
axes_slider = plt.subplot(grid[0, 0]) 
slider = Slider(axes_slider, 'Channel', valmin=0, valmax=255, valinit=128) 

# Plot the radio buttons 
axes_button = plt.subplot(grid[1, 0]) 
button = RadioButtons(axes_button, ('Gradient', 'Channel'), active=1) 

plt.tight_layout(h_pad=0) 
plt.subplots_adjust(left=.2, right=.9) 

def buttonupdate(val): 
    if val == "Gradient": 
     axes_slider.clear() 
     slider.__init__(axes_slider, 'Gradient', valmin=-1, valmax=1, valinit=0)   
    else: 
     axes_slider.clear() 
     slider.__init__(axes_slider, 'Channel', valmin=0, valmax=255, valinit=128) 
    plt.gcf().canvas.draw_idle() 

def sliderupdate(val): 
    if slider.label.get_text() == 'Gradient': 
     #do something depending on gradient value 
     pass 
    else: 
     #do something depending on channel value 
     pass 

# Register call-backs with widgets 
slider.on_changed(sliderupdate) 
button.on_clicked(buttonupdate) 

plt.show()