2017-04-14 2 views
1

À l'intérieur du rappel associé à une instance matplotlib.widgets.Slider, je souhaite modifier les attributs Slider valmin, valmax et val, puis redessiner le Slider. Quand j'essaie de le redessiner, rien ne se passe.Comment forcer redessiner un widget après avoir changé certains de ses attributs?

Avant que le rappel ne se termine, j'appelle plt.draw() et, alors que le reste de l'intrigue est correctement mis à jour, le Slider a le même aspect qu'avant. J'ai également essayé d'appeler draw() sur le Axes du Slider, et encore aucune modification visible.

Comment puis-je forcer un retrait de l'instance Slider après modification de ses attributs?

Thansk!

MISE À JOUR

Voici un petit programme qui démontre la question (avec une boîte de dialogue brut). Le comportement voulu est qu'en cliquant sur une valeur différente du bouton radio, le curseur change la plage de valeurs, la valeur actuelle et l'étiquette. Ce qui se passe est au contraire que lorsque vous cliquez sur « dégradé » le curseur cesse de répondre (ne peut pas être traîné plus), et en cliquant sur « dégradé » ou « Channel » le curseur est pas mis à jour, en dépit d'un appel à 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

Je vais essayer de trouver un programme court qui reproduit encore le problème. – Fanta

+0

J'ai mis à jour la question avec un exemple de code. – Fanta

Répondre

1

Le curseur lui-même est une classe qui héberge et gère certains paramètres. Il n'a pas de méthode de tirage. Cela dit, il ne suffit pas de définir uniquement les paramètres du curseur, il faut également mettre à jour les axes dans lesquels le curseur se trouve. A la fin, tout se résume exactement aux étapes d'initialisation du curseur. Vous pouvez donc appeler simplement la fonction,du silder.

Je recommande fortement d'utiliser deux fonctions différentes, l'une pour changer le curseur qui est appelé sur les clics de bouton et l'autre pour les choses qui devraient se produire si la valeur du curseur est ajustée.

Voici un exemple de travail:

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()