Интерактивный сюжет matplotlib с двумя ползунками - PullRequest
50 голосов
/ 14 июля 2011

Я использовал matplotlib , чтобы создать график, который зависит от 8 переменных. Я хотел бы изучить, как меняется сюжет, когда я меняю некоторые из них. Я создал сценарий, который вызывает matplotlib и генерирует различные снимки, которые позже я конвертирую в фильм, это не плохо, но немного неуклюже.

  1. Интересно, смогу ли я как-нибудь взаимодействовать с регенерацией графика, используя клавиши клавиатуры, чтобы увеличить / уменьшить значения некоторых переменных и сразу увидеть, как меняется график.

  2. Каков наилучший подход для этого?

  3. Также, если вы можете указать мне интересные ссылки или ссылку с примером сюжета с двумя ползунками?

Ответы [ 5 ]

65 голосов
/ 14 июля 2011

В дополнение к тому, что упомянуто @triplepoint, взгляните на виджет слайдера.

На странице примеров matplotlib приведен пример .Это графическая ползунок, а не привязки к клавиатуре, но она отлично работает для того, что вы хотите сделать.

Также обратите внимание, что для обеспечения того, чтобы ползунки и кнопки оставались отзывчивыми и не собирали мусор, ссылки на объекты (amp_slider, freq_slider и т. Д.) Должны поддерживаться самим.

(я делаю это вики сообщества, так как я просто копирую из примера. Этот конкретный примеручит вредных привычек (например, from pylab import *), но это помогает понять. Пример был исправлен, чтобы избежать использования 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

6 голосов
/ 14 июля 2011

Matplotlib обладает довольно приятным графическим интерфейсом. Есть несколько примеров документации в архиве исходного кода matplotlib, в / examples / user_interfaces и matplotlib> / examples / event_handling. Конкретно по обработке ключей это: http://matplotlib.sourceforge.net/examples/event_handling/keypress_demo.html

Я сделал нечто похожее на то, к чему вы стремитесь:

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

Я использовал это для переключения между отображением различных изображений в стеке при нажатии клавиш, но вы должны иметь возможность вводить логику для изменения ваших значений с помощью ввода с клавиатуры.

Если вы хотите сделать что-то вроде ввода значений пользователем, я думаю, что в примерах есть варианты для диалоговых окон, но если вы просто хотите увеличить / уменьшить количество переменных, просто определение пар клавиатуры для них таким образом может хорошо работать

2 голосов
/ 13 августа 2012

Используйте waitforbuttonpress(timeout=0.001), тогда график будет видеть ваши тики мыши.

1 голос
/ 14 июля 2011

Я не думаю, что простое построение графиков с использованием plt.plot позволит вам сделать это.Вам нужно будет сделать собственный скрипт / приложение с графическим интерфейсом, вставив в него Matplotlib.В настоящее время Matplotlib поддерживает все основные наборы инструментов GUI - PyGTK +, PyQt4 и wxPython.
Я использую wxPython, и встраивание в него matplotlib довольно просто.Аналогичное должно быть в случае с другими инструментами GUI.Вы можете получить всю необходимую для этого информацию в книге - enter image description here

Она доступна на amazon здесь .

0 голосов
/ 12 марта 2019

Для ноутбуков с ipython или jupyter вы можете использовать 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) );

См. Документацию здесь: https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html

...