Reputation: 43
I'm trying to create an interactive matplotlib plot of a multidimensional function with three parameters to vary. The problem is that the parameters can vary over a very large range, so I'd rather not use sliders but directly type the value I'd like. Basically, I'd like to recreate the canonical example below where instead of sliders I'd like text boxes in which I can input parameters
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.35)
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t,s, lw=2, color='red')
plt.axis([0, 1, -10, 10])
ax.plot(t,t)
axcolor = 'lightgoldenrodyellow'
axamp = plt.axes([0.25, 0.25, 0.65, 0.03], axisbg=axcolor)
axfreq = plt.axes([0.25, 0.2, 0.65, 0.03], axisbg=axcolor)
sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)
def update(val):
amp = samp.val
freq = sfreq.val
l.set_ydata(amp*np.sin(2*np.pi*freq*t))
fig.canvas.draw_idle()
sfreq.on_changed(update)
samp.on_changed(update)
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')
def reset(event):
sfreq.reset()
samp.reset()
button.on_clicked(reset)
plt.show()
Upvotes: 4
Views: 4446
Reputation: 97281
You can add a GUI panel to the figure window. Here is an example to use the Qt4Agg backend, and add a QDockWidget
to the main figure window, and then you can add QWidgets to the dock window.
import numpy as np
import matplotlib
matplotlib.use("Qt4Agg") # This program works with Qt only
import pylab as pl
fig, ax1 = pl.subplots()
t = np.linspace(0, 10, 200)
line, = ax1.plot(t, np.sin(t))
### control panel ###
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtCore import Qt
def update():
freq = float(textbox.text())
y = np.sin(2*np.pi*freq*t)
line.set_data(t, y)
fig.canvas.draw_idle()
root = fig.canvas.manager.window
panel = QtGui.QWidget()
hbox = QtGui.QHBoxLayout(panel)
textbox = QtGui.QLineEdit(parent = panel)
textbox.textChanged.connect(update)
hbox.addWidget(textbox)
panel.setLayout(hbox)
dock = QtGui.QDockWidget("control", root)
root.addDockWidget(Qt.BottomDockWidgetArea, dock)
dock.setWidget(panel)
######################
pl.show()
Here is the screen:
Upvotes: 4