Plot con pyqt4 y qwt5 Segunda parte

En esta segunda parte las funciones que se añadirán a la grafica son las siguientes:

    Una línea (marker) que corte el gráfico por el centro, Y= 0
    Un indicador de coordenadas.
    Marcar cada punto en la grafica en el que se hace clic.
    Además de crear una línea horizontal donde se haga clic que “corte” la grafica.
Para crear el indicador de coordenadas se utiliza la clase QwtPlotPicker. La estructura general de este objeto es la siguiente:
  1. QwtPlotPicker (int xAxis,
  2. int yAxis,
  3. int selectionFlags,
  4. RubberBand rubberBand,
  5. DisplayMode trackerMode,
  6. QwtPlotCanvas *)
Donde:
xAxis: Es el eje de donde toma el valor mostrado con respecto al eje X. El plot puede tener dos ejes X, uno a la izquierda y otro a la derecha. En es elemento se indica de donde se tomará el valor de referencia.
yAxis: Tiene la misma función que xAxis pero tomando el eje Y como referencia.
selectionFlags: Puede seleccionarse entre PointSelection que devuelve un valor tipo QPoint o RectSelection que devuelve un valor tipo QRect.
Rubberband: Establece la forma de las líneas que indican el punto a seleccionar. Puede ser, una cruz que muestra lar coordenadas X y Y, una línea horizontal que solo muestra las coordenadas del eje X, una línea vertical que solo muestra las coordenadas del eje Y, sin líneas, una elipse, y un rectángulo. Estos dos últimos modos, solo se pueden utilizar con el tipo RectSelection.
DisplayMode: Puede ser siempre visible, visible cuando solo cuando se haga clic o invisible.
QwtPlotCanvas: Es el objeto tipo plot al que se le va a insertar el selector (picker).
En el siguiente ejemplo se creará un selector que indique las coordenadas X y Y, que sea visible solo cuando se haga clic en el plot, con el color de texto en blanco, y color de las líneas en color magenta.
  1. picker = Qwt.QwtPlotPicker(Qwt.QwtPlot.xBottom,
  2.         Qwt.QwtPlot.yLeft,
  3.         Qwt.QwtPicker.PointSelection,
  4.         Qwt.QwtPlotPicker.CrossRubberBand,
  5.         Qwt.QwtPicker.ActiveOnly,
  6.     plot.canvas())
  7.     picker.setTrackerPen(Qt.QPen(Qt.Qt.white)) #text color
  8.     picker.setRubberBandPen(Qt.QPen(Qt.Qt.magenta))
Cuando ejecutamos el programa, al hacer clic en cualquier punto del plot obtenemos lo siguiente:
Ahora crearemos una línea horizontal que corta el gráfico por la mitad, esto se hace con un objeto qwtMarker. Solo necesitamos indicar las coordenadas de la línea, si es horizontal o vertical, y el color. Esto se hace de la siguiente manera:


  1. #line cutting by the middle of the plot
  2. marker =  Qwt.QwtPlotMarker()
  3. marker.setLineStyle(Qwt.QwtPlotMarker.HLine)
  4. marker.setYValue(0)
  5. marker.setLinePen(Qt.QPen(Qt.Qt.white))
  6. marker.attach(plot)
Al ejecutar el programa veremos lo siguiente:
El siguiente punto es crear una marca en cada punto de la grafica en el que hagamos clic. Lo primero que debemos hacer es detectar cuando se hace clic en el plot. Para esto conectaremos la señal “selected” emitida por el objeto QwtPicker cuando se hace clic el plot, activando nuestro propio slot, en este caso se llamara plotClicked. A continuación se muestra la manera de hacerlo:
  1. #connect
  2. self.pickerX.connect(self.pickerX,
  3.     Qt.SIGNAL('selected(const QwtDoublePoint&)'),
  4.     self.plotClicked)
Conectamos la señal “selected” que corresponde a la señal emitida cuando se hace clic (hasta levantar el dedo del botón) con el slot plotClicked. Esta señal nos devuelve un tipo QwtDoublePoint, que es representado por una lista de dos puntos tipo doble. El objeto pickerX es el que creamos anteriormente tipo QwtPlotPicker. Modificando la línea que crea el objeto plotX, para que también cree el objeto pickerX queda así:
  1. self.plotX, self.pickerX= self.createPlot('green')
Para crear la marca, utilizaremos nuevamente el objeto QwtPlotMarker, pero esta vez dibujaremos un circulo, en lugar de una línea horizontal, utilizando la funcion setSymbol y construyendo el objeto QwtSymbol cuya estructura es:
  1. QwtSymbol (Style, const QBrush &, const QPen &, const QSize &)
donde:
Style: Es la forma del símbolo a dibujar. Puede ser un triangulo, una cruz, una estrella, una elipse y más.
QBrush: Es el color de relleno.
QPen: Es el color de contorno.
Qsize: Es el tamaño del símbolo.
La función queda así:
  1. def plotClicked(self, pos):
  2.     marker = Qwt.QwtPlotMarker()
  3.     marker.setXValue(pos.x())
  4.     marker.setYValue(pos.y())
  5.     marker.setSymbol(Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse,
  6.         Qt.QBrush(Qt.Qt.yellow),
  7.         Qt.QPen(Qt.Qt.magenta),
  8.         Qt.QSize(10, 10)))
  9.     marker.attach(self.plotX)
  10.     self.plotX.replot()
corriendo el programa:
Por ultimo crearemos otro objeto QwtPlotMarker, que cortará la gráfica de X=0 a X=100. Esto podría utilizarse para indicar un límite en la amplitud de la onda, donde la onda cruce este marcador, que ejecute alguna función.
  1. #this creates the line mark
  2. triggerMark =  Qwt.QwtPlotMarker()
  3. triggerMark.setLineStyle(Qwt.QwtPlotMarker.HLine)
  4. triggerMark.setLinePen(Qt.QPen(Qt.Qt.red))
Después de crear el marcador,  modificamos la función crearPlot() para que también devuelva el objeto QwtPlotMarker:
  1. return plot, picker,triggerMark
Creamos una variable triggerMarkX, que contendrá el objeto triggerMark, y vinculamos el marcador con el plot:
  1. self.plotX, self.pickerX, self.triggerMarkX= self.createPlot('green')
  2. self.triggerMarkX.attach(self.plotX)
Por último agregamos a la función crearPlot(), lo necesario para que al hacer clic, el marcador se mueva a la posición indicada:
  1.    def plotClicked(self, pos):
  2.         marker = Qwt.QwtPlotMarker()
  3.         marker.setXValue(pos.x())
  4.         marker.setYValue(pos.y())
  5.         marker.setSymbol(Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse,
  6.             Qt.QBrush(Qt.Qt.yellow),
  7.             Qt.QPen(Qt.Qt.magenta),
  8.             Qt.QSize(10, 10)))
  9.         marker.attach(self.plotX)
  10.         self.triggerMarkX.setYValue(trunc(pos.y()))
  11.         self.plotX.replot()
La función trunc, es para redondear el valor de la posición Y.
Este es el resultado:
Aquí termina el primer ejemplo. Código fuente completo:
  1. import sys
  2. from PyQt4 import QtCore, QtGui,  Qt
  3. from Ui_ejemploqwt_ui import Ui_MainWindow
  4. import PyQt4.Qwt5 as Qwt
  5. from PyQt4.Qwt5.anynumpy import *
  6. class testAnalogUI(QtGui.QMainWindow)
  7.   
  8.     def __init__(self, parent=None):
  9.         QtGui.QWidget.__init__(self, parent)
  10.         self.ui = Ui_MainWindow()
  11.         self.ui.setupUi(self)
  12.        
  13.         self.plotX, self.pickerX, self.triggerMarkX= self.createPlot('green')
  14.         self.triggerMarkX.attach(self.plotX)
  15.         #connect
  16.         self.pickerX.connect(self.pickerX, Qt.SIGNAL('selected(const QwtDoublePoint&)'), self.plotClicked)
  17.        
  18.         #add the plot widget to the vertical layout created in qtdesigner
  19.         self.ui.vlEjeX.addWidget(self.plotX)          
  20.        
  21.     def createPlot(self, color):
  22.         #en esta parte se crea el plot que seria todo el marco y los numeros "el cascaron"
  23.         plot = Qwt.QwtPlot()
  24.         plot.setCanvasBackground(QtGui.QColor("black"))
  25.         plot.setAxisTitle(Qwt.QwtPlot.xBottom, 'X Axis')
  26.         plot.setAxisTitle(Qwt.QwtPlot.yLeft, 'Y Axis')
  27.         plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 100)
  28.         plot.setAxisScale(Qwt.QwtPlot.yLeft, -100, 100,10)
  29.         plot.setAxisAutoScale(Qwt.QwtPlot.xBottom)
  30.                
  31.         #creation of the curve
  32.         curve = Qwt.QwtPlotCurve('')
  33.         curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
  34.         pen = QtGui.QPen(QtGui.QColor(color))
  35.         pen.setWidth(2)
  36.         curve.setPen(pen)
  37.         curve.attach(plot)

Descargar archivo

0 comentarios:

Publicar un comentario