1

我是 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_())

问候克里斯托夫

4

1 回答 1

0

好的,我对您的代码进行了一些更改以使其正常工作:

  1. 更改函数def plot(self, R, axes):定义def plot(self, R):
  2. 相应地self.plot(position, self.mpl.axes)将通话更改为Routself.plot(position)
  3. 通过以下方式更改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_())
于 2014-02-04T17:01:53.157 回答