我是python的真正初学者,并尝试将qslider连接到matplotlibwidget。 这意味着如果我更改滑块的值,图表应该更改。似乎值正确变化,而图表保持不变。谁能告诉我如何将滑块的变化与图形连接起来?这是我到目前为止的算法:
# -*- coding: utf-8 -*-
"""
Created on Tue Feb 04 16:48:12 2014
@author: Christoph
"""
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure
from matplotlib import rcParams
import numpy as np
import scipy.constants as const
import sys
rcParams['font.size'] = 9
class MatplotlibWidget(Canvas):
"""
MatplotlibWidget inherits PyQt4.QtGui.QWidget
and matplotlib.backend_bases.FigureCanvasBase
Options: option_name (default_value)
-------
parent (None): parent widget
title (''): figure title
xlabel (''): X-axis label
ylabel (''): Y-axis label
xlim (None): X-axis limits ([min, max])
ylim (None): Y-axis limits ([min, max])
xscale ('linear'): X-axis scale
yscale ('linear'): Y-axis scale
width (4): width in inches
height (3): height in inches
dpi (100): resolution in dpi
hold (False): if False, figure will be cleared each time plot is called
Widget attributes:
-----------------
figure: instance of matplotlib.figure.Figure
axes: figure axes
Example:
-------
self.widget = MatplotlibWidget(self, yscale='log', hold=True)
from numpy import linspace
x = linspace(-10, 10)
self.widget.axes.plot(x, x**2)
self.wdiget.axes.plot(x, x**3)
"""
def __init__(self, parent=None, title='', xlabel='', ylabel='',
xlim=None, ylim=None, xscale='linear', yscale='linear',
width=4, height=3, dpi=100, hold=False):
self.figure = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.figure.add_subplot(111)
self.axes.set_title(title)
self.axes.set_xlabel(xlabel)
self.axes.set_ylabel(ylabel)
if xscale is not None:
self.axes.set_xscale(xscale)
if yscale is not None:
self.axes.set_yscale(yscale)
if xlim is not None:
self.axes.set_xlim(*xlim)
if ylim is not None:
self.axes.set_ylim(*ylim)
self.axes.hold(hold)
Canvas.__init__(self, self.figure)
self.setParent(parent)
Canvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
Canvas.updateGeometry(self)
def sizeHint(self):
w, h = self.get_width_height()
return QtGui.QSize(w, h)
def minimumSizeHint(self):
return QtGui.QSize(10, 10)
class ApplicationWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
# Graphics Window
self.mpl = MatplotlibWidget(self, title='Graph',
xlabel='x',
ylabel='y',
hold=True)
self.mpl.setGeometry(0,0,1300,800)
self.setGeometry(0, 30, 1680, 800)
# Slider Resistance
title1=QtGui.QLabel(self)
title1.setText('R')
title1.move(1400,10)
self.value1=QtGui.QLabel(self)
self.value1.setText('1')
self.value1.move(1550,40)
cb=QtGui.QSlider(QtCore.Qt.Horizontal, self)
cb.setGeometry(1400,40,100,30)
cb.setMinimum(1)
cb.setMaximum(10000)
cb.valueChanged.connect(self.Rout)
self.plot(1, self.mpl.axes)
def Rout(self, position):
self.value1.setText('%i' %position)
self.plot(position, self.mpl.axes)
def plot(self, R, axes):
x=np.linspace(0,5,1001)
B=0.035
n1=0.115
H=2.06227451e-15
n2=1.37040209e-01
gamma=0.001*const.e
C=0.13
x=np.array(x)
diodetheo = H*(np.exp((const.e*x*n2)/(const.k*300))-1)
zaehler = 1+np.exp((B-C+n1*x)*const.e/(const.k*300))
nenner = 1+np.exp((B-C-n1*x)*const.e/(const.k*300))
A=8.7476434*10**(29)*gamma
D=gamma/2
klammer2 = (const.pi/2)+np.arctan((C-n1*x)/D)
y1 = A*np.log(zaehler/nenner)*klammer2
# plt.figure()
# plt.plot(x, diodetheo, 'g')
# plt.show()
indup=[]
inddown=[]
iup=[]
idown=[]
theo = (y1+diodetheo)*(10**(-12))*(100)/4
for i, Volt in enumerate(x):
xup=np.linspace(0,Volt,i+1)
last=Volt/R-xup/R
diff=np.array(last)-np.array(theo[0:i+1])
inter=np.where(np.diff(np.sign(diff)))[0]
if inter.size==0:
inter=np.array([0])
indup.append(inter[0])
inddown.append(inter[-1])
iup.append(theo[inter[0]])
idown.append(theo[inter[-1]])
up = np.array(iup)
down = np.array(idown)
down=np.flipud(down)
ytotal=np.concatenate((up, down))
xneg=np.flipud(x)
xtotal=np.concatenate((x,xneg))
#plt.figure()
#plt.plot(xtotal, ytotal, 'g')
#plt.show()
axes.plot(xtotal, ytotal, 'r')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
win = ApplicationWindow()
win.show()
sys.exit(app.exec_())
问候 克里斯托弗
答案 0 :(得分:0)
好的,我已对代码进行了一些更改,以使其有效:
def plot(self, R, axes):
def plot(self, R):
self.plot(position, self.mpl.axes)
上的电话Rout
相应更改为self.plot(position)
通过以下方式更改上一个axes.plot(xtotal, ytotal, 'r')
功能的最后一行plot
:
self.mpl.axes.clear() #clear the previous plot
self.mpl.axes.plot(xtotal, ytotal, 'r') #replot
self.mpl.figure.canvas.draw() #redraw the canvas
说明:
首先,如果轴已经是self.mpl
的属性并且易于访问,则无需将轴传递给绘图函数。其次,当你制作另一个图时,你需要清除前一个图并刷新画布。
接下来所有代码都经过修改,以便于使用复制粘贴:
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure
from matplotlib import rcParams
import numpy as np
import scipy.constants as const
import sys
rcParams['font.size'] = 9
class MatplotlibWidget(Canvas):
"""
MatplotlibWidget inherits PyQt4.QtGui.QWidget
and matplotlib.backend_bases.FigureCanvasBase
Options: option_name (default_value)
-------
parent (None): parent widget
title (''): figure title
xlabel (''): X-axis label
ylabel (''): Y-axis label
xlim (None): X-axis limits ([min, max])
ylim (None): Y-axis limits ([min, max])
xscale ('linear'): X-axis scale
yscale ('linear'): Y-axis scale
width (4): width in inches
height (3): height in inches
dpi (100): resolution in dpi
hold (False): if False, figure will be cleared each time plot is called
Widget attributes:
-----------------
figure: instance of matplotlib.figure.Figure
axes: figure axes
Example:
-------
self.widget = MatplotlibWidget(self, yscale='log', hold=True)
from numpy import linspace
x = linspace(-10, 10)
self.widget.axes.plot(x, x**2)
self.wdiget.axes.plot(x, x**3)
"""
def __init__(self, parent=None, title='', xlabel='', ylabel='',
xlim=None, ylim=None, xscale='linear', yscale='linear',
width=4, height=3, dpi=100, hold=False):
self.figure = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.figure.add_subplot(111)
self.axes.set_title(title)
self.axes.set_xlabel(xlabel)
self.axes.set_ylabel(ylabel)
if xscale is not None:
self.axes.set_xscale(xscale)
if yscale is not None:
self.axes.set_yscale(yscale)
if xlim is not None:
self.axes.set_xlim(*xlim)
if ylim is not None:
self.axes.set_ylim(*ylim)
self.axes.hold(hold)
Canvas.__init__(self, self.figure)
self.setParent(parent)
Canvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
Canvas.updateGeometry(self)
def sizeHint(self):
w, h = self.get_width_height()
return QtGui.QSize(w, h)
def minimumSizeHint(self):
return QtGui.QSize(10, 10)
class ApplicationWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
# Graphics Window
self.mpl = MatplotlibWidget(self, title='Graph',
xlabel='x',
ylabel='y',
hold=True)
self.mpl.setGeometry(0,0,1300,800)
self.setGeometry(0, 30, 1680, 800)
# Slider Resistance
title1=QtGui.QLabel(self)
title1.setText('R')
title1.move(1400,10)
self.value1=QtGui.QLabel(self)
self.value1.setText('1')
self.value1.move(1550,40)
cb=QtGui.QSlider(QtCore.Qt.Horizontal, self)
cb.setGeometry(1400,40,100,30)
cb.setMinimum(1)
cb.setMaximum(10000)
cb.valueChanged.connect(self.Rout)
self.plot(1)
def Rout(self, position):
self.value1.setText('%i' %position)
self.plot(position)
def plot(self, R):
x=np.linspace(0,5,1001)
B=0.035
n1=0.115
H=2.06227451e-15
n2=1.37040209e-01
gamma=0.001*const.e
C=0.13
x=np.array(x)
diodetheo = H*(np.exp((const.e*x*n2)/(const.k*300))-1)
zaehler = 1+np.exp((B-C+n1*x)*const.e/(const.k*300))
nenner = 1+np.exp((B-C-n1*x)*const.e/(const.k*300))
A=8.7476434*10**(29)*gamma
D=gamma/2
klammer2 = (const.pi/2)+np.arctan((C-n1*x)/D)
y1 = A*np.log(zaehler/nenner)*klammer2
# plt.figure()
# plt.plot(x, diodetheo, 'g')
# plt.show()
indup=[]
inddown=[]
iup=[]
idown=[]
theo = (y1+diodetheo)*(10**(-12))*(100)/4
for i, Volt in enumerate(x):
xup=np.linspace(0,Volt,i+1)
last=Volt/R-xup/R
diff=np.array(last)-np.array(theo[0:i+1])
inter=np.where(np.diff(np.sign(diff)))[0]
if inter.size==0:
inter=np.array([0])
indup.append(inter[0])
inddown.append(inter[-1])
iup.append(theo[inter[0]])
idown.append(theo[inter[-1]])
up = np.array(iup)
down = np.array(idown)
down=np.flipud(down)
ytotal=np.concatenate((up, down))
xneg=np.flipud(x)
xtotal=np.concatenate((x,xneg))
#plt.figure()
#plt.plot(xtotal, ytotal, 'g')
#plt.show()
self.mpl.axes.clear()
self.mpl.axes.plot(xtotal, ytotal, 'r')
self.mpl.figure.canvas.draw()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
win = ApplicationWindow()
win.show()
sys.exit(app.exec_())