带有两个滑块的交互式 matplotlib 绘图

发布于 2024-11-24 17:44:25 字数 320 浏览 2 评论 0原文

我使用 ma​​tplotlib 创建了一些图,该图取决于 8 个变量。我想研究一下当我改变其中一些内容时情节如何变化。我创建了一些脚本,调用 ma​​tplotlib 脚本并生成不同的快照,然后将其转换成电影,这还不错,但有点笨拙。

  1. 我想知道是否可以使用键盘按键与绘图重新生成进行交互,以增加/减少某些变量的值,并立即查看绘图如何变化。

  2. 最好的方法是什么?

  3. 此外,您是否可以向我指出有趣的链接或仅包含两个滑块的绘图示例的链接?

I used matplotlib to create some plot, which depends on 8 variables. I would like to study how the plot changes when I change some of them. I created some script that calls the matplotlib one and generates different snapshots that later I convert into a movie, it is not bad, but a bit clumsy.

  1. I wonder if somehow I could interact with the plot regeneration using keyboard keys to increase / decrease values of some of the variables and see instantly how the plot changes.

  2. What is the best approach for this?

  3. Also if you can point me to interesting links or a link with a plot example with just two sliders?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

独自唱情﹋歌 2024-12-01 17:44:25

除了 @triplepoint 提到的之外,还可以看看滑块小部件。

matplotlib 示例页面上有一个示例。它是一个图形滑块而不是键盘绑定,但它非常适合您想要做的事情。

另请注意,为了保证滑块和按钮保持响应且不会被垃圾收集,对对象(amp_sliderfreq_slider 等)的引用应由您自己维护。

(我正在制作这个社区 wiki,因为我只是从示例中复制粘贴。这个特定示例教导了坏习惯(例如 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], facecolor=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], facecolor=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], facecolor=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

In addition to what @triplepoint mentioned, have a look at the slider widget.

There's an example on the matplotlib examples page. It's a graphical slider bar rather than keyboard bindings, but it works quite well for what you want to do.

Also note that to guarantee the sliders and buttons remain responsive and not garbage-collected, references to the objects (amp_slider, freq_slider, etc.) should be maintained by yourself.

(I'm making this community wiki, as I'm just copy-pasting from the example. This particular example teaches bad habits (e.g. from pylab import *), but it gets the point across. The example has been fixed to avoid the use of 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], facecolor=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], facecolor=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], facecolor=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

尝蛊 2024-12-01 17:44:25

我按照建议检查了 jupyter 中的小部件,它们工作得很好。
示例脚本上传到 GitHub https://github。 com/LeonidBystrykh/course-python-for-beginners/blob/master/Interactive_dots.ipynb

from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
import matplotlib.pyplot as plt, random

def series(dots, colr):
    a,b=[],[]
    for i in range(dots):
        a.append(random.randint(1,100))
        b.append(random.randint(1,100))
    plt.scatter(a,b, c=colr)
    return()
interact(series, dots=(1,100,1), colr=["red","orange","brown"]);

图像副本位于

我可以更改数量交互式点或其颜色

I followed the advice to check widgets in jupyter, and they work very well.
The example script is uploaded in GitHub https://github.com/LeonidBystrykh/course-python-for-beginners/blob/master/Interactive_dots.ipynb

from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
import matplotlib.pyplot as plt, random

def series(dots, colr):
    a,b=[],[]
    for i in range(dots):
        a.append(random.randint(1,100))
        b.append(random.randint(1,100))
    plt.scatter(a,b, c=colr)
    return()
interact(series, dots=(1,100,1), colr=["red","orange","brown"]);

The image copy is below

I can change number of dots or their color interactively

温柔少女心 2024-12-01 17:44:25

Matplotlib 有一些相当不错的 GUI 功能。 matplotlib 的源 tarball 中有一些文档示例,位于 /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()

我用它来切换在按键时在堆栈中显示不同的图像,但是你应该能够放置逻辑来修改给定键盘输入的值。

如果您想做诸如拥有用户输入值之类的事情,我认为这些示例具有对话框选项,但如果您只想增加/减少一些变量,那么以这种方式为它们定义键盘对可能会很好用

Matplotlib has some fairly nice gui functionality. There are some documentation examples in the source tarball of matplotlib, in /examples/user_interfaces and matplotlib>/examples/event_handling. Specifically on keyhandling is: http://matplotlib.sourceforge.net/examples/event_handling/keypress_demo.html

I have done something kind of similar to what you are aiming for:

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

I was using this to shift through displaying different images in a stack on keypresses, but you should be able to put logic in to modify your values given keyboard input.

If you want to do things like have the user input values, I think the examples have options for dialog boxes, but if you just want to increment/decrement a number of variables, just defining keyboard pairs for them in this manner might work well

渡你暖光 2024-12-01 17:44:25

对于 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

For ipython or jupyter notebooks you can use 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) );

See documentation here:
https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html

狠疯拽 2024-12-01 17:44:25

使用 waitforbuttonpress(timeout=0.001) 然后绘图将看到您的鼠标滴答声。

Use waitforbuttonpress(timeout=0.001) then plot will see your mouse ticks.

剪不断理还乱 2024-12-01 17:44:25

您还可以考虑使用 Quib​​bler 软件包

Quibbler 自动使您的普通 matplotlib 图形具有交互性。无需编写回调函数。

请参阅 Quib​​bler 文档中的一些示例。特别是,请参阅带有两个滑块的绘图的具体示例。

from pyquibbler import iquib, initialize_quibbler
initialize_quibbler()
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import numpy as np
%matplotlib tk

# Figure setup:
fig = plt.figure(figsize=(4, 6))

axs = fig.add_axes([0, 0.36, 1, 0.64])
axs.axis('square')
axs.axis((-10, 10, -10, 10))
axs.axis('off')

axs_slider1 = fig.add_axes([0.3, 0.16, 0.55, 0.03])
axs_slider2 = fig.add_axes([0.3, 0.06, 0.55, 0.03])

# Defining quib input variables:
nPoints = iquib(120)
nCycles = iquib(30)

# Define downstream function quib calculations based on the quib inputs:
phi = np.linspace(0, 2 * np.pi * nCycles, nPoints)
r = np.linspace(0, 10, nPoints)

# Plot the data:
axs.plot(r * np.cos(phi), r * np.sin(phi), 'r-')

# Create quib-linked slider widgets:
Slider(ax=axs_slider1, label='nCycles', valmin=0, valmax=200, valstep=1, valinit=nCycles)
Slider(ax=axs_slider2, label='nPoints', valmin=0, valmax=200, valstep=1, valinit=nPoints)

为了透明起见:我是《唱唱反调》的开发者之一。

Quibbler 实现matplotlib 滑块

You could also consider using the Quibbler package.

Quibbler automatically makes your normal matplotlib graphics interactive. There is no need to write callback functions.

See some examples in the Quibbler docs. In particular, see a specific example of a plot with two sliders.

from pyquibbler import iquib, initialize_quibbler
initialize_quibbler()
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import numpy as np
%matplotlib tk

# Figure setup:
fig = plt.figure(figsize=(4, 6))

axs = fig.add_axes([0, 0.36, 1, 0.64])
axs.axis('square')
axs.axis((-10, 10, -10, 10))
axs.axis('off')

axs_slider1 = fig.add_axes([0.3, 0.16, 0.55, 0.03])
axs_slider2 = fig.add_axes([0.3, 0.06, 0.55, 0.03])

# Defining quib input variables:
nPoints = iquib(120)
nCycles = iquib(30)

# Define downstream function quib calculations based on the quib inputs:
phi = np.linspace(0, 2 * np.pi * nCycles, nPoints)
r = np.linspace(0, 10, nPoints)

# Plot the data:
axs.plot(r * np.cos(phi), r * np.sin(phi), 'r-')

# Create quib-linked slider widgets:
Slider(ax=axs_slider1, label='nCycles', valmin=0, valmax=200, valstep=1, valinit=nCycles)
Slider(ax=axs_slider2, label='nPoints', valmin=0, valmax=200, valstep=1, valinit=nPoints)

For transparency: I am one of the developers of Quibbler.

Quibbler implementation of matplotlib Sliders

南烟 2024-12-01 17:44:25

我不认为简单地使用 plt.plot 绘制图表就可以让您做到这一点。您需要通过将 Matplotlib 嵌入其中来自己制作自定义 GUI 脚本/应用程序。目前,Matplotlib 支持所有主要的 GUI 工具包 - PyGTK+、PyQt4 和 wxPython。
我使用 wxPython 并且在其中嵌入 matplotlib 相当容易。其他 GUI 工具包的情况也应该类似。您可以在书中获得所需的所有信息 -
在此处输入图像描述

可在亚马逊上购买 此处

I don't think that simply plotting graphs using plt.plot will allow you to do this. You will need to yourself make a custom GUI script/app by embedding Matplotlib into it. Currently, Matplotlib supports all the major GUI toolkits - PyGTK+, PyQt4 and wxPython.
I use wxPython and embedding matplotlib in it is fairly easy. Similar should be case with the other GUI toolkits. You can get all the information you need for this in the book -
enter image description here

It is available on amazon here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文