Color plot auf Matplotlibwidget

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
qwert2
User
Beiträge: 18
Registriert: Donnerstag 8. Januar 2015, 12:53

Hi,
Ich habe bassierend auf meinem Matplotlibwidget aus meiner Library eine zusätliche Funktion Matplotlibwidget.color_plot eingebaut. Diese soll den Betrag einer Komplexen Funktion farbkodiert darstellen. Weder Label noch Graph werden dargestellt. Die .py aus meiner xml:

Code: Alles auswählen

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'interface.ui'
#
# Created: Sat Mar 28 11:05:56 2015
#      by: PyQt4 UI code generator 4.9.6
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.mplwidget = MatplotlibWidget(self.centralwidget)
        self.mplwidget.setGeometry(QtCore.QRect(190, 80, 400, 300))
        self.mplwidget.setObjectName(_fromUtf8("mplwidget"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))

from matplotlibwidget import MatplotlibWidget
Mein Matplotlibwidget (abgeändert):

Code: Alles auswählen


__version__ = "1.0.0"

from PyQt4.QtGui import QSizePolicy
from PyQt4.QtCore import QSize

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure

from matplotlib import rcParams
rcParams['font.size'] = 9

import numpy as np

class MatplotlibWidget(Canvas):

    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, QSizePolicy.Expanding, QSizePolicy.Expanding)
        Canvas.updateGeometry(self)

    def sizeHint(self):
        w, h = self.get_width_height()
        return QSize(w, h)

    def minimumSizeHint(self):
        return QSize(10, 10)
            
    def color_plot(self,xval,yval,zval,xlabel='',xunit='',ylabel='',
                    yunit='',zlabel='',zunit=''):
                        
        self.figure.clear()
        self.figure.subplots_adjust(bottom=0.15,left=0.17) 
        self.axes.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
        self.axes.ticklabel_format(style='sci', axis='y', scilimits=(0,0))
        self.axes.axis([xval.min(),xval.max(),yval.min(),yval.max()])
        x_color=self.axes.pcolormesh(xval,yval,np.absolute(zval).T)
        self.figure.colorbar(x_color,orientation="vertical",
                             label=zlabel+' ['+zunit+']',format='%.0e')
        self.axes.set_xlabel(xlabel+' ['+xunit+']')
        self.axes.set_ylabel(ylabel+' ['+yunit+']')
        self.draw()

#===============================================================================
#   Example
#===============================================================================
if __name__ == '__main__':
    import sys
    from PyQt4.QtGui import QMainWindow, QApplication
    from numpy import linspace
    
    class ApplicationWindow(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
            self.mplwidget = MatplotlibWidget(self, title='Example',
                                              xlabel='Linear scale',
                                              ylabel='Log scale',
                                              hold=True, yscale='log')
            self.mplwidget.setFocus()
            self.setCentralWidget(self.mplwidget)
            self.plot(self.mplwidget.axes)
            
        def plot(self, axes):
            x = linspace(-10, 10)
            axes.plot(x, x**2)
            axes.plot(x, x**3)
        
    app = QApplication(sys.argv)
    win = ApplicationWindow()
    win.show()
    sys.exit(app.exec_())
Auf diesem Widget möchte ich eine Funktion plotten:

Code: Alles auswählen

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.uic import *
import numpy as np
import plot_options as po

application = QApplication(sys.argv)  
frame=loadUi('interface.ui')

def f(x,y):
    return (x**2+y**2)*np.exp(np.complex(x,y))

x=np.array([-2.0,-1.0,0.0,1.0,2.0])
y=np.array([-2.0,-1.0,0.0,1.0,2.0])

z=[]
for xi in x:
    z_temp=[]
    for yi in y:
        z_temp.append(f(xi,yi))
    z.append(z_temp)

z=np.array(z)

frame.mplwidget.color_plot(x,y,z,xlabel='x',
                        xunit='-',ylabel='y',
                        yunit='-',zlabel='z',zunit='-')
    
frame.show()
application.exec_()
Was mache ich falsch?
BlackJack

@qwert2: Da sollte, wenn man das im Terminal startet, die Meldung kommen, das `frame.mplwidget` kein Attribut `color_plot` hat. Ich sehe nämlich nicht wo der erste Quelltext überhaupt eingebunden wird, womit `frame.mplwidget` den Datentyp hat der in der ``interface.ui`` festgelegt wurde.
qwert2
User
Beiträge: 18
Registriert: Donnerstag 8. Januar 2015, 12:53

Ich bin mir nicht sicher, ob ich dich richtig verstehe. Das MainWindow wird aus interface.ui als Object "frame" importiert (xml kann ich bei Bedarf auch posten). In Mainwindow wird die Klasse Matplotlibwidget importiert, die diese Funktion besitzt. Somit ist sie auch in complex_function.py enthalten. Das Canvas mit Colorbar wird ja auch angezeigt, leider nicht der Plot
BlackJack

@qwert2: Der erste Quelltext in Deinem Beitrag: Lösch mal die Datei. Und starte dann den dritten Quelltext. Da sollte sich keine Änderung ergeben, denn ich sehe nicht wo der erste Quelltext irgendwo verwendet wird. Folglich ist auch egal was dort drin steht.
qwert2
User
Beiträge: 18
Registriert: Donnerstag 8. Januar 2015, 12:53

Ich habe den ersten auch nicht direkt eingebunden. Ich habe den aus der zugehörigen xml kompiliert. Die xml (interface.ui):

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="MatplotlibWidget" name="mplwidget">
    <property name="geometry">
     <rect>
      <x>190</x>
      <y>80</y>
      <width>400</width>
      <height>300</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>MatplotlibWidget</class>
   <extends>QWidget</extends>
   <header>matplotlibwidget</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

BlackJack

@qwert2: Vielleicht könnte man erst einmal klären ob der Plot so überhaupt korrekt ist bevor man sich zusätzlich noch Qt dazu holt. Vergleich mal Dein `x` und `y` beispielsweise mit dem Plot aus der Gallerie in der Numpy-Dokumentation. Die verwenden dort *zwei*dimensionale Arrays für diese beiden Argumente.
qwert2
User
Beiträge: 18
Registriert: Donnerstag 8. Januar 2015, 12:53

Das habe ich schon ausprobiert und es hat auch funktioniert. Es muss irgendwie mit Qt zusammenhängen.
Antworten