web-dev-qa-db-fra.com

Graphique matplotlib interactif avec deux curseurs

J'ai utilisé matplotlib pour créer un tracé, qui dépend de 8 variables. Je voudrais étudier comment l'intrigue change lorsque j'en change certains. J'ai créé un script qui appelle --- matplotlib et génère différents instantanés que plus tard je convertis en film, ce n'est pas mauvais, mais un peu maladroit.

  1. Je me demande si, d'une manière ou d'une autre, je pourrais interagir avec la régénération du tracé à l'aide des touches du clavier pour augmenter/diminuer les valeurs de certaines variables et voir instantanément comment le tracé change.

  2. Quelle est la meilleure approche pour cela?

  3. Aussi, si vous pouvez me diriger vers des liens intéressants ou un lien avec un exemple d'intrigue avec seulement deux curseurs?

52
Open the way

En plus de ce que @triplepoint a mentionné, jetez un œil au widget curseur.

Il y a un exemple sur la page d'exemples de matplotlib . C'est une barre de défilement graphique plutôt que des liaisons de clavier, mais cela fonctionne assez bien pour ce que vous voulez faire.

Notez également que pour garantir que les curseurs et les boutons restent réactifs et non récupérés, les références aux objets (amp_slider, freq_slider, etc.) doit être entretenu par vous-même.

(Je crée ce wiki communautaire, car je ne fais que copier-coller de l'exemple. Cet exemple particulier enseigne les mauvaises habitudes (par exemple from pylab import *), mais il fait passer le message. L'exemple a été corrigé pour éviter l'utilisation de pylab.)

from numpy import pi, sin
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

def signal(amp, freq):
    return amp * sin(2 * pi * freq * t)

axis_color = 'lightgoldenrodyellow'

fig = plt.figure()
ax = fig.add_subplot(111)

# Adjust the subplots region to leave some space for the sliders and buttons
fig.subplots_adjust(left=0.25, bottom=0.25)

t = np.arange(0.0, 1.0, 0.001)
amp_0 = 5
freq_0 = 3

# Draw the initial plot
# The 'line' variable is used for modifying the line later
[line] = ax.plot(t, signal(amp_0, freq_0), linewidth=2, color='red')
ax.set_xlim([0, 1])
ax.set_ylim([-10, 10])

# Add two sliders for tweaking the parameters

# Define an axes area and draw a slider in it
amp_slider_ax  = fig.add_axes([0.25, 0.15, 0.65, 0.03], axisbg=axis_color)
amp_slider = Slider(amp_slider_ax, 'Amp', 0.1, 10.0, valinit=amp_0)

# Draw another slider
freq_slider_ax = fig.add_axes([0.25, 0.1, 0.65, 0.03], axisbg=axis_color)
freq_slider = Slider(freq_slider_ax, 'Freq', 0.1, 30.0, valinit=freq_0)

# Define an action for modifying the line when any slider's value changes
def sliders_on_changed(val):
    line.set_ydata(signal(amp_slider.val, freq_slider.val))
    fig.canvas.draw_idle()
amp_slider.on_changed(sliders_on_changed)
freq_slider.on_changed(sliders_on_changed)

# Add a button for resetting the parameters
reset_button_ax = fig.add_axes([0.8, 0.025, 0.1, 0.04])
reset_button = Button(reset_button_ax, 'Reset', color=axis_color, hovercolor='0.975')
def reset_button_on_clicked(mouse_event):
    freq_slider.reset()
    amp_slider.reset()
reset_button.on_clicked(reset_button_on_clicked)

# Add a set of radio buttons for changing color
color_radios_ax = fig.add_axes([0.025, 0.5, 0.15, 0.15], axisbg=axis_color)
color_radios = RadioButtons(color_radios_ax, ('red', 'blue', 'green'), active=0)
def color_radios_on_clicked(label):
    line.set_color(label)
    fig.canvas.draw_idle()
color_radios.on_clicked(color_radios_on_clicked)

plt.show()

Example

65
Joe Kington

Matplotlib a des fonctionnalités gui assez agréables. Il y a quelques exemples de documentation dans l'archive tar source de matplotlib, dans/examples/user_interfaces et matplotlib>/examples/event_handling. Plus précisément sur la manipulation des touches est: http://matplotlib.sourceforge.net/examples/event_handling/keypress_demo.html

J'ai fait quelque chose de similaire à ce que vous visez:

import numpy as np
import pylab

class plotter:
    def __init__(self, initial_values):
        self.values
        self.fig = pylab.figure()
        pylab.gray()
        self.ax = self.fig.add_subplot(111)
        self.draw()
        self.fig.canvas.mpl_connect('key_press_event',self.key)

    def draw(self):
        im = your_function(self.values)
        pylab.show()
        self.ax.imshow(im)

    def key(self, event):
        if event.key=='right':
            self.values = modify()
        Elif event.key == 'left':
            self.values = modify()

        self.draw()
        self.fig.canvas.draw()

J'utilisais cela pour passer à l'affichage de différentes images dans une pile sur des touches, mais vous devriez pouvoir mettre de la logique pour modifier vos valeurs en fonction de la saisie au clavier.

Si vous voulez faire des choses comme avoir les valeurs d'entrée utilisateur, je pense que les exemples ont des options pour les boîtes de dialogue, mais si vous voulez juste incrémenter/décrémenter un certain nombre de variables, juste définir des paires de clavier pour elles de cette manière pourrait bien fonctionner

6
triplepoint217

Utilisez waitforbuttonpress(timeout=0.001) puis le tracé verra les tiques de votre souris.

2
sema

Je ne pense pas que tracer simplement des graphiques en utilisant plt.plot vous permettra de le faire. Vous devrez créer vous-même un script/application GUI personnalisé en y incorporant Matplotlib. Actuellement, Matplotlib prend en charge toutes les principales boîtes à outils de l'interface graphique - PyGTK +, PyQt4 et wxPython.
J'utilise wxPython et l'intégration de matplotlib est assez simple. Cela devrait être le cas avec les autres boîtes à outils GUI. Vous pouvez obtenir toutes les informations dont vous avez besoin dans le livre - enter image description here

Il est disponible sur Amazon ici .

1
Pushpak Dagade

Pour les blocs-notes ipython ou jupyter, vous pouvez utiliser ipywidgets:

from ipywidgets import *
def update(w=0,h=0):
    print(h+w)

interact(update, w= widgets.IntSlider(value=1, min=0, max=7, step=1) , 
                 h= widgets.IntSlider(value=1, min=0, max=7, step=1) );

Voir la documentation ici: https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html

0
Alexey Birukov