30 from math
import log10, ceil
34 import PyQt4.Qwt5
as Qwt
36 import Ui_dbplot_scaling
40 MAC =
"qt_mac_set_native_menubar" in dir()
44 applicationName =
'dBplot'
52 class DbPlot(QMainWindow, Ui_dbplot.Ui_Plot):
109 def __init__(self, XData, leftYData, rightXData = None, rightYData = None, leftWidth = None, rightWidth = None, leftYmin = None, leftYmax = None, rightYmin = None, rightYmax = None, Xmin = None, Xmax = None, windowTitle = None, tabTitle = None, title=None, leftYNames=None, rightYNames=None, leftYVisible=None, rightYVisible=None, XLabel=None, leftYLabel=None, rightYLabel=None, leftYColors=None, rightYColors=None, textLabel=None, Xunits=None, leftYunits=None, rightYunits = None, parent=None):
111 super(DbPlot, self).
__init__(parent)
113 self.setAttribute(Qt.WA_DeleteOnClose)
115 if windowTitle
is not None: self.setWindowTitle(windowTitle)
116 self.statusBar.showMessage(
'Use toolbar buttons to zoom, add or delete markers')
119 self.toolBar.addAction(QWhatsThis.createAction(self.toolBar))
132 self.
moveKnob = Qwt.QwtSlider(self, Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot)
133 self.moveKnob.setScaleMaxMajor(24)
134 self.moveKnob.setScaleMaxMinor(5)
135 self.verticalLayout.addWidget(self.
moveKnob)
138 self.moveKnob.setVisible(
False)
142 if textLabel
is not None:
145 textLabel = textLabel.split(
'\n')
149 newLabel = QLabel(st, self.centralWidget)
150 self.label.append (newLabel)
151 self.verticalLayout.addWidget(newLabel)
274 self.
addTab(XData = XData, leftYData = leftYData, rightXData = rightXData, rightYData = rightYData, leftWidth = leftWidth, rightWidth = rightWidth, leftYmin = leftYmin, leftYmax = leftYmax, rightYmin = rightYmin, rightYmax = rightYmax, Xmin = Xmin, Xmax = Xmax , tabTitle = tabTitle, title = title, leftYNames = leftYNames, rightYNames = rightYNames, leftYVisible = leftYVisible, rightYVisible = rightYVisible, XLabel = XLabel, leftYLabel = leftYLabel, rightYLabel = rightYLabel, leftYColors = leftYColors, rightYColors = rightYColors, Xunits = Xunits, leftYunits = leftYunits, rightYunits = rightYunits)
277 self.resize(800, 600)
342 def addTab(self, XData, leftYData, rightXData = None, rightYData = None, leftWidth = None, rightWidth = None, leftYmin = None, leftYmax = None, rightYmin = None, rightYmax = None, Xmin = None, Xmax = None, tabTitle = None, title=None, leftYNames=None, rightYNames=None, leftYVisible=None, rightYVisible=None, XLabel=None, leftYLabel=None, rightYLabel=None, leftYColors=None, rightYColors=None, Xunits=None, leftYunits=None, rightYunits=None, replaceTab=None):
343 if replaceTab
is None:
347 verticalLayout_tab = QVBoxLayout(tab)
348 self.tabWidget.addTab(tab,
"Plot")
351 self.XData.append(XData)
352 self.leftYData.append(leftYData)
353 self.rightXData.append(rightXData)
354 self.rightYData.append(rightYData)
357 self.Xunits.append(
' ' + Xunits
if Xunits
is not None else '' )
358 self.leftYunits.append(
' ' + leftYunits
if leftYunits
is not None else '' )
359 self.rightYunits.append(
' ' + rightYunits
if rightYunits
is not None else '' )
363 self.scalingDlg.append(scalingDlg)
364 scalingDlg.setWindowTitle(
'Axis scaling: %s' % tabTitle)
367 self.hPlot.append(Qwt.QwtPlot(tab))
368 verticalLayout_tab.addWidget(self.
hPlot[nTab])
369 hPlot = self.
hPlot[nTab]
372 hPlot.plotLayout().setAlignCanvasToScales(
True)
373 grid = Qwt.QwtPlotGrid()
375 grid.setPen(QPen(Qt.black, 0, Qt.DotLine))
378 hPlot.setCanvasBackground(Qt.white)
382 self.
XData[nTab] = XData
388 self.
Xunits[nTab] =
' ' + Xunits
if Xunits
is not None else ''
389 self.
leftYunits[nTab] =
' ' + leftYunits
if leftYunits
is not None else ''
390 self.
rightYunits[nTab] =
' ' + rightYunits
if rightYunits
is not None else ''
392 hPlot = self.
hPlot[nTab]
396 if tabTitle
is not None: self.tabWidget.setTabText(nTab, tabTitle)
397 if title
is not None: hPlot.setTitle(title)
398 if rightYData
is not None: hPlot.enableAxis(Qwt.QwtPlot.yRight)
401 if XLabel
is not None: hPlot.setAxisTitle(Qwt.QwtPlot.xBottom, XLabel)
402 if leftYLabel
is not None: hPlot.setAxisTitle(Qwt.QwtPlot.yLeft, leftYLabel)
403 if rightYLabel
is not None: hPlot.setAxisTitle(Qwt.QwtPlot.yRight, rightYLabel)
406 defaultColors = [Qt.blue, Qt.red, QColor(0, 175, 0), QColor(191, 0, 191), Qt.black, QColor(0, 191, 191), QColor(191, 191, 0) ]
409 if type(leftYData[0]).__name__
not in [
'ndarray',
'list']: leftYData = [ leftYData ]
410 elif type(leftYData).__name__ ==
'ndarray' and leftYData.ndim == 2: leftYData = [ leftYData ]
412 if type(XData[0]).__name__
not in [
'ndarray',
'list']: XData = [ XData ]
414 if rightYData
is not None:
415 if type(rightYData[0]).__name__
not in [
'ndarray',
'list']: rightYData = [ rightYData ]
416 elif type(rightYData).__name__ ==
'ndarray' and rightYData.ndim == 2: rightYData = [ rightYData ]
418 if rightXData
is not None:
419 if type(rightXData[0]).__name__
not in [
'ndarray',
'list']: rightXData = [ rightXData ]
421 if leftYNames
is not None:
422 if type(leftYNames).__name__
not in [
'ndarray',
'list']: leftYNames = [ leftYNames ]
423 self.leftYNames.append(leftYNames)
424 if rightYNames
is not None:
425 if type(rightYNames).__name__
not in [
'ndarray',
'list']: rightYNames = [ rightYNames ]
426 self.rightYNames.append(rightYNames)
427 if leftYVisible
is not None:
428 if type(leftYVisible).__name__
not in [
'ndarray',
'list']: leftYVisible = [ leftYVisible]
429 if rightYVisible
is not None:
430 if type(rightYVisible).__name__
not in [
'ndarray',
'list']: rightYVisible = [ rightYVisible ]
431 if leftYColors
is not None:
432 if type(leftYColors).__name__
not in [
'ndarray',
'list']: leftYColors = [ leftYColors ]
433 if rightYColors
is not None:
434 if type(rightYColors).__name__
not in [
'ndarray',
'list']: rightYColors = [ rightYColors ]
435 if leftWidth
is not None:
436 if type(leftWidth).__name__
not in [
'ndarray',
'list']: leftWidth = [ leftWidth ]
437 if rightWidth
is not None:
438 if type(rightWidth).__name__
not in [
'ndarray',
'list']: rightWidth = [ rightWidth ]
445 if replaceTab
is not None:
446 for CF
in self.
leftYCurves[nTab]: CF.deleteCurves()
451 if leftYVisible
is None: leftYVisible = [
True for n
in leftYData ]
452 else:
assert len(leftYVisible) == len(leftYData)
454 if rightYData
is not None:
455 if rightYVisible
is None: rightYVisible = [
True for n
in rightYData ]
456 else:
assert len(rightYVisible) == len(rightYData)
460 if leftYNames
is not None:
assert len(leftYData) == len(leftYNames)
461 if leftYColors
is not None:
assert len(leftYData) == len(leftYColors)
462 if leftWidth
is not None:
assert len(leftYData) == len(leftWidth)
465 for n
in range(0, len(leftYData)):
467 xdata = XData[0]
if len(XData) == 1
else XData[n]
469 assert len(xdata) == len(leftYData[n])
470 name = leftYNames[n]
if leftYNames
is not None else 'curve #%d' % n
471 color = leftYColors[n]
if leftYColors
is not None else defaultColors[n % len(defaultColors)]
472 width = leftWidth[n]
if leftWidth
is not None else None
474 CF =
CurveFamily(hPlot, name, xdata, leftYData[n], Qwt.QwtPlot.yLeft, leftYVisible[n], color, width)
475 leftYCurves.append(CF)
479 if rightYData
is not None:
480 if rightYNames
is not None:
assert len(rightYData) == len(rightYNames)
481 if rightYColors
is not None:
assert len(rightYData) == len(rightYColors)
482 if rightWidth
is not None:
assert len(rightYData) == len(rightWidth)
485 for n
in range(0, len(rightYData)):
487 tmp = XData
if rightXData
is None else rightXData
490 xdata = tmp[0]
if len(tmp) == 1
else tmp[n]
492 assert len(xdata ) == len(rightYData[n])
493 name = rightYNames[n]
if rightYNames
is not None else 'curve #%d' % n
494 color = rightYColors[n]
if rightYColors
is not None else defaultColors[(n + len(leftYData)) % len(defaultColors)]
495 width = rightWidth[n]
if rightWidth
is not None else None
497 CF =
CurveFamily(hPlot, name, xdata, rightYData[n], Qwt.QwtPlot.yRight, rightYVisible[n], color, width)
498 rightYCurves.append(CF)
500 if replaceTab
is None:
507 zoomerLeft = Qwt.QwtPlotZoomer(Qwt.QwtPlot.xBottom, Qwt.QwtPlot.yLeft, Qwt.QwtPicker.DragSelection, Qwt.QwtPicker.AlwaysOff, hPlot.canvas())
508 self.zoomerLeft.append(zoomerLeft)
509 self.
zoomerLeft[nTab].setRubberBandPen(QPen(Qt.green))
511 self.connect(zoomerLeft, SIGNAL(
'zoomed(QwtDoubleRect)'),
lambda value: self.
getPrecision(nTab))
512 self.connect(zoomerLeft, SIGNAL(
'zoomed(QwtDoubleRect)'),
lambda value: self.
updateMoveKnobRange())
514 zoomerRight = Qwt.QwtPlotZoomer(Qwt.QwtPlot.xTop, Qwt.QwtPlot.yRight, Qwt.QwtPicker.PointSelection | Qwt.QwtPicker.DragSelection, Qwt.QwtPicker.AlwaysOff, hPlot.canvas())
515 self.zoomerRight.append(zoomerRight)
516 self.
zoomerRight[nTab].setRubberBand(Qwt.QwtPicker.NoRubberBand)
520 pickerLeft =
MyPicker( self, nTab, Qwt.QwtPlot.xBottom, Qwt.QwtPlot.yLeft, Qwt.QwtPicker.PointSelection | Qwt.QwtPicker.ClickSelection, Qwt.QwtPlotPicker.CrossRubberBand, Qwt.QwtPicker.AlwaysOn, hPlot.canvas())
521 pickerLeft.setTrackerPen(QPen(Qt.black))
522 self.pickerLeft.append(pickerLeft)
525 self.setCurves.append(
EditCurvesDlg(leftYCurves, rightYCurves, self))
535 if replaceTab
is None:
536 self.leftYCurves.append(leftYCurves)
537 self.rightYCurves.append(rightYCurves)
540 self.masks.append( [] )
541 self.maskNames.append( [] )
544 self.markers.append( [] )
547 self.precX.append(
None)
548 self.precY.append(
None)
557 for curve
in self.
masks[nTab]:
558 maskVisibility.append(curve.isVisible())
562 self.
hPlot[nTab].setAxisAutoScale(Qwt.QwtPlot.yLeft)
563 self.
hPlot[nTab].setAxisAutoScale(Qwt.QwtPlot.yRight)
564 self.
hPlot[nTab].setAxisAutoScale(Qwt.QwtPlot.xBottom)
565 self.
hPlot[nTab].replot()
566 dataLeftYmax, dataLeftYmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.yLeft)
567 dataRightYmax, dataRightYmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.yRight)
568 dataXmax, dataXmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.xBottom)
571 for n, curve
in enumerate(self.
masks[nTab]):
572 curve.attach(self.
hPlot[nTab])
573 curve.setVisible(maskVisibility[n])
574 legendItem = self.
legends[nTab].find(curve)
575 legendItem.setChecked(maskVisibility[n])
578 leftZoomerBaseRect, rightZoomerBaseRect = self.
autoScaleBase[nTab].updateZoomerBase(dataXmin, dataXmax, dataLeftYmin, dataLeftYmax, dataRightYmin, dataRightYmax)
579 if leftZoomerBaseRect
is not None: self.
zoomerLeft[nTab].setZoomBase( leftZoomerBaseRect )
580 if rightZoomerBaseRect
is not None: self.
zoomerRight[nTab].setZoomBase( rightZoomerBaseRect )
587 self.actionCurves.setChecked(
False)
590 if len(self.
markers[nTab]) > 0:
591 for marker
in self.
markers[nTab]:
597 self.
precX[nTab] =
None
598 self.
precY[nTab] =
None
602 for (axis, groupBox, min_Counter, max_Counter)
in zip( [ Qwt.QwtPlot.yLeft, Qwt.QwtPlot.yRight, Qwt.QwtPlot.xBottom ],
608 minorTicks = self.
hPlot[nTab].axisScaleDiv(axis).ticks(Qwt.QwtScaleDiv.MinorTick)
609 mediumTicks = self.
hPlot[nTab].axisScaleDiv(axis).ticks(Qwt.QwtScaleDiv.MediumTick)
610 majorTicks = self.
hPlot[nTab].axisScaleDiv(axis).ticks(Qwt.QwtScaleDiv.MajorTick)
612 maxminScale = maxScale - minScale
613 majorStep = majorTicks[1] - majorTicks[0]
614 mediumStep = mediumTicks[0] - majorTicks[0]
if len(mediumTicks) > 0
else majorStep
615 minorStep = minorTicks[0] - majorTicks[0]
if len(minorTicks) > 0
else mediumStep
616 NminorSteps = int(round(majorStep/minorStep))
623 min_Counter.setStepButton1(1)
624 min_Counter.setStepButton2(NminorSteps)
625 max_Counter.setStepButton1(1)
626 max_Counter.setStepButton2(NminorSteps)
628 max_Counter.setRange(minScale, maxScale, minorStep)
629 max_Counter.setValue(maxScale)
630 min_Counter.setRange(minScale, maxScale, minorStep)
631 min_Counter.setValue(minScale)
633 groupBox.setToolTip(
'Double arrow increments/decrements %g, simple arrow %g' % (minorStep*NminorSteps, minorStep) )
634 groupBox.setChecked(
False)
637 if replaceTab
is None:
641 self.connect(self.
scalingDlg[nTab].leftY_groupBox, SIGNAL(
'toggled(bool)'),
lambda value: self.
setManualScaling(value, Qwt.QwtPlot.yLeft) )
646 self.connect(self.
scalingDlg[nTab].rightY_groupBox, SIGNAL(
'toggled(bool)'),
lambda value: self.
setManualScaling(value, Qwt.QwtPlot.yRight) )
647 self.connect(self.
scalingDlg[nTab].autoRightY_pushButton, SIGNAL(
'pressed()'),
lambda : self.
setAutoScaling(Qwt.QwtPlot.yRight, self.
scalingDlg[nTab].rightY_groupBox) )
651 self.connect(self.
scalingDlg[nTab].X_groupBox, SIGNAL(
'toggled(bool)'),
lambda value: self.
setManualScaling(value, Qwt.QwtPlot.xBottom) )
657 if leftYmin: self.
scalingDlg[nTab].leftYmin_Counter.setValue(leftYmin)
658 if leftYmax: self.
scalingDlg[nTab].leftYmax_Counter.setValue(leftYmax)
659 if leftYmin
or leftYmax: self.
scalingDlg[nTab].leftY_groupBox.setChecked(
True)
660 else: self.
scalingDlg[nTab].leftY_groupBox.setChecked(
False)
661 self.
hPlot[nTab].setAxisScale(Qwt.QwtPlot.yLeft, self.
scalingDlg[nTab].leftYmin_Counter.value(), self.
scalingDlg[nTab].leftYmax_Counter.value())
663 if rightYmin: self.
scalingDlg[nTab].rightYmin_Counter.setValue(rightYmin)
664 if rightYmax: self.
scalingDlg[nTab].rightYmax_Counter.setValue(rightYmax)
665 if rightYmin
or rightYmax: self.
scalingDlg[nTab].rightY_groupBox.setChecked(
True)
666 else: self.
scalingDlg[nTab].rightY_groupBox.setChecked(
False)
667 self.
hPlot[nTab].setAxisScale(Qwt.QwtPlot.yRight, self.
scalingDlg[nTab].rightYmin_Counter.value(), self.
scalingDlg[nTab].rightYmax_Counter.value() )
669 if Xmin: self.
scalingDlg[nTab].Xmin_Counter.setValue(Xmin)
670 if Xmax: self.
scalingDlg[nTab].Xmax_Counter.setValue(Xmax)
671 if Xmin
or Xmax: self.
scalingDlg[nTab].X_groupBox.setChecked(
True)
672 else: self.
scalingDlg[nTab].X_groupBox.setChecked(
False)
673 self.
hPlot[nTab].setAxisScale(Qwt.QwtPlot.xBottom, self.
scalingDlg[nTab].Xmin_Counter.value(), self.
scalingDlg[nTab].Xmax_Counter.value() )
675 if replaceTab
is None:
677 legend = Qwt.QwtLegend()
678 legend.setItemMode(Qwt.QwtLegend.CheckableItem)
680 hPlot.insertLegend(legend, Qwt.QwtPlot.RightLegend)
681 self.legends.append(legend)
682 self.connect(self.
hPlot[nTab], SIGNAL(
'legendChecked(QwtPlotItem*, bool)'), self.
showCurve)
689 legendLayout = legend.contentsWidget().children()[0]
692 for family
in leftYCurves + rightYCurves: family.setLegendItems(legend=legend, updateLegend=updateLegend)
698 if replaceTab
is None:
702 if replaceTab
is None:
724 def addMask(self, nTab, XData, YData, axis, name, color, type, visible = True, transpar = 64):
727 yLeftScale = self.
hPlot[nTab].axisScaleDiv(Qwt.QwtPlot.yLeft)
728 yRightScale = self.
hPlot[nTab].axisScaleDiv(Qwt.QwtPlot.yRight)
729 xBottomScale = self.
hPlot[nTab].axisScaleDiv(Qwt.QwtPlot.xBottom)
730 leftYmin, leftYmax, rightYmin, rightYmax, Xmin, Xmax = yLeftScale.lowerBound(), yLeftScale.upperBound(), yRightScale.lowerBound(), yRightScale.upperBound(), xBottomScale.lowerBound(), xBottomScale.upperBound()
732 if type ==
'Lower': baseline = -1e7
733 elif type ==
'Upper': baseline = 1e7
735 assert type.lower()
in [
'upper',
'lower']
736 assert axis.lower()
in [
'left',
'right']
737 curve = Qwt.QwtPlotCurve(name)
739 semitrans = QColor(color)
740 semitrans.setAlpha(transpar)
741 curve.setPen(QPen(semitrans))
742 curve.setBrush(semitrans)
743 curve.setVisible(visible)
744 curve.setBaseline( baseline)
745 curve.attach(self.
hPlot[nTab])
746 if axis.lower() ==
'left': curve.setYAxis(Qwt.QwtPlot.yLeft)
747 elif axis.lower() ==
'right': curve.setYAxis(Qwt.QwtPlot.yRight)
750 XData = np.concatenate(( np.array([ XData[0]] ), XData, np.array([ XData[-1]]) ))
751 YData = np.concatenate(( np.array([ baseline ]), YData, np.array([ baseline ]) ))
753 curve.setData(XData, YData)
754 legendItem = self.
legends[nTab].find(curve)
755 legendItem.setChecked(visible)
756 idenWidth = legendItem.identifierWidth()
757 legendItem.setIdentifierMode(Qwt.QwtLegendItem.ShowSymbol)
758 symbol = Qwt.QwtSymbol( Qwt.QwtSymbol.Rect, semitrans, QPen(semitrans), QSize(2*idenWidth, 2*idenWidth) )
759 legendItem.setSymbol(symbol)
761 self.
masks[nTab].append(curve)
765 self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.yLeft, leftYmin, leftYmax )
766 self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.yRight, rightYmin, rightYmax )
767 self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.xBottom, Xmin, Xmax )
769 self.
hPlot[nTab].replot()
779 for nTab
in range(self.
Ntabs):
780 for curve
in self.
masks[nTab]: curve.detach()
781 self.
masks[nTab] = []
783 self.
hPlot[nTab].replot()
800 def update(self, nTab, XData, leftYData, rightXData = None, rightYData=None, textLabel=None, autoScaleBottomX=False, autoScaleLeftY=False, autoScaleRightY=False):
803 yLeftScale = self.
hPlot[nTab].axisScaleDiv(Qwt.QwtPlot.yLeft)
804 yRightScale = self.
hPlot[nTab].axisScaleDiv(Qwt.QwtPlot.yRight)
805 xBottomScale = self.
hPlot[nTab].axisScaleDiv(Qwt.QwtPlot.xBottom)
807 rightYmax, rightYmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.yRight)
811 if textLabel
is not None:
812 textLabel = textLabel.split(
'\n')
813 assert len(textLabel) == len(self.
label)
814 for n
in range(len(textLabel)): self.
label[n].setText(textLabel[n])
817 if type(XData[0]).__name__
not in [
'ndarray',
'list']: XData = [ XData ]
819 if type(leftYData[0]).__name__
not in [
'ndarray',
'list']: leftYData = [ leftYData ]
820 elif type(leftYData).__name__ ==
'ndarray' and leftYData.ndim == 2: leftYData = [ leftYData ]
822 if rightXData
is not None:
823 if type(rightXData[0]).__name__
not in [
'ndarray',
'list']: rightXData = [ rightXData ]
825 if rightYData
is not None:
826 if type(rightYData[0]).__name__
not in [
'ndarray',
'list']: rightYData = [ rightYData ]
827 elif type(rightYData).__name__ ==
'ndarray' and rightYData.ndim == 2: rightYData = [ rightYData ]
829 dataXmin, dataXmax, dataLeftYmin, dataLeftYmax, dataRightYmin, dataRightYmax = np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf
831 assert len(self.
leftYCurves[nTab]) == len(leftYData)
834 xdata = XData[0]
if len(XData) == 1
else XData[n]
838 cfXmin, cfXmax, cfYmin, cfYmax = CF.updateCurves(xdata, leftYData[n])
846 if rightYData
is not None:
850 tmp = XData
if rightXData
is None else rightXData
853 xdata = tmp[0]
if len(tmp) == 1
else tmp[n]
857 cfXmin, cfXmax, cfYmin, cfYmax = CF.updateCurves(xdata, rightYData[n])
867 for curve
in self.
masks[nTab]:
868 maskVisibility.append(curve.isVisible())
872 self.
hPlot[nTab].setAxisAutoScale(Qwt.QwtPlot.yLeft)
873 self.
hPlot[nTab].setAxisAutoScale(Qwt.QwtPlot.yRight)
874 self.
hPlot[nTab].setAxisAutoScale(Qwt.QwtPlot.xBottom)
875 self.
hPlot[nTab].replot()
876 dataLeftYmax, dataLeftYmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.yLeft)
877 dataRightYmax, dataRightYmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.yRight)
878 dataXmax, dataXmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.xBottom)
881 for n, curve
in enumerate(self.
masks[nTab]):
882 curve.attach(self.
hPlot[nTab])
883 curve.setVisible(maskVisibility[n])
884 legendItem = self.
legends[nTab].find(curve)
885 legendItem.setChecked(maskVisibility[n])
888 leftZoomerBaseRect, rightZoomerBaseRect = self.
autoScaleBase[nTab].updateZoomerBase(dataXmin, dataXmax, dataLeftYmin, dataLeftYmax, dataRightYmin, dataRightYmax)
889 if leftZoomerBaseRect
is not None: self.
zoomerLeft[nTab].setZoomBase( leftZoomerBaseRect )
890 if rightZoomerBaseRect
is not None: self.
zoomerRight[nTab].setZoomBase( rightZoomerBaseRect )
893 self.
scalingDlg[nTab].Xmin_Counter.setRange(dataXmin, dataXmax, self.
scalingDlg[nTab].Xmin_Counter.step())
894 self.
scalingDlg[nTab].Xmax_Counter.setRange(dataXmin, dataXmax, self.
scalingDlg[nTab].Xmax_Counter.step())
895 if self.
scalingDlg[nTab].Xmin_Counter.value() == dataXmax: self.
scalingDlg[nTab].Xmin_Counter.setValue(dataXmin)
896 if self.
scalingDlg[nTab].Xmax_Counter.value() == dataXmin:self.
scalingDlg[nTab].Xmax_Counter.setValue(dataXmax)
898 self.
scalingDlg[nTab].leftYmin_Counter.setRange(dataLeftYmin, dataLeftYmax, self.
scalingDlg[nTab].leftYmin_Counter.step())
899 self.
scalingDlg[nTab].leftYmax_Counter.setRange(dataLeftYmin, dataLeftYmax, self.
scalingDlg[nTab].leftYmax_Counter.step())
900 if self.
scalingDlg[nTab].leftYmin_Counter.value() == dataLeftYmax: self.
scalingDlg[nTab].leftYmin_Counter.setValue(dataLeftYmin)
901 if self.
scalingDlg[nTab].leftYmax_Counter.value() == dataLeftYmin: self.
scalingDlg[nTab].leftYmax_Counter.setValue(dataLeftYmax)
903 self.
scalingDlg[nTab].rightYmin_Counter.setRange(dataRightYmin, dataRightYmax, self.
scalingDlg[nTab].rightYmin_Counter.step())
904 self.
scalingDlg[nTab].rightYmax_Counter.setRange(dataRightYmin, dataRightYmax, self.
scalingDlg[nTab].rightYmax_Counter.step())
905 if self.
scalingDlg[nTab].rightYmin_Counter.value() == dataRightYmax: self.
scalingDlg[nTab].rightYmin_Counter.setValue(dataRightYmin)
906 if self.
scalingDlg[nTab].rightYmax_Counter.value() == dataRightYmin: self.
scalingDlg[nTab].rightYmax_Counter.setValue(dataRightYmax)
910 self.
scalingDlg[nTab].leftY_groupBox.setChecked(
False)
912 self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.yLeft, leftYmin, leftYmax )
915 self.
scalingDlg[nTab].rightY_groupBox.setChecked(
False)
917 self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.yRight, rightYmin, rightYmax )
920 self.
scalingDlg[nTab].X_groupBox.setChecked(
False)
922 self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.xBottom, Xmin, Xmax )
925 for marker
in self.
markers[nTab]: marker.updatePosition()
927 self.
hPlot[nTab].replot()
935 if not self.actionNewMarker.isChecked():
return
937 nTab = self.tabWidget.currentIndex()
939 if len(self.
markers[nTab]) == 0:
940 QMessageBox.warning(self,
"WARNING",
'There are no markers to delete in this Tab.')
943 markerDel = self.
markers[nTab][-1]
945 message =
'Delete marker: %s' % markerDel.label().text()
946 reply = QMessageBox.question(self,
"%s - Delete Marker" % applicationName, message, QMessageBox.Yes | QMessageBox.No)
948 if reply == QMessageBox.Yes:
950 self.
hPlot[nTab].replot()
951 self.
markers[nTab].remove(markerDel)
964 if len(self.
markers[nTab]) == 0:
965 QMessageBox.warning(self,
"WARNING",
'There are no markers in this Tab.')
968 hPlot = self.
hPlot[nTab]
970 scX, scY = point.x(), point.y()
980 maxRightY, minRightY = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.yRight)
982 for marker
in self.
markers[nTab]:
983 if not marker.curve.isVisible():
continue
985 if marker.axis == Qwt.QwtPlot.yLeft:
986 if marker.y > maxLeftY
or marker.y < minLeftY:
continue
987 distY = hPlot.transform(Qwt.QwtPlot.yLeft, marker.y) - scY
989 elif marker.axis == Qwt.QwtPlot.yRight:
990 if marker.y > maxRightY
or marker.y < minRightY:
continue
991 distY = hPlot.transform(Qwt.QwtPlot.yRight, marker.y) - scY
993 distX = hPlot.transform(Qwt.QwtPlot.xBottom, marker.x) - scX
994 dist2 = distX**2 + distY**2
997 markerSelected = marker
1001 markerRadius2 = (markerSelected.symbol().size().height()**2 + markerSelected.symbol().size().width()**2) / 4
1002 if minDist2 <= markerRadius2:
1003 return markerSelected
1005 QMessageBox.warning(self,
"WARNING",
"No marker selected")
1015 if not self.actionDeleteMarker.isChecked():
return
1017 nTab = self.tabWidget.currentIndex()
1018 hPlot = self.
hPlot[nTab]
1023 if markerDel
is not None:
1024 markerDel.setSymbol(markerDel.symbolDel)
1029 message =
'Delete marker: %s' % markerDel.label().text()
1030 reply = QMessageBox.question(self,
"%s - Delete Marker" % applicationName, message, QMessageBox.Yes | QMessageBox.No)
1032 if reply == QMessageBox.Yes:
1034 self.
markers[nTab].remove(markerDel)
1037 markerDel.setSymbol(markerDel.symbolNormal)
1048 if not self.actionMoveMarker.isChecked():
return
1050 nTab = self.tabWidget.currentIndex()
1062 hPlot = self.
hPlot[nTab]
1064 if markerMove
is not None:
1065 markerMove.setSymbol(markerMove.symbolMove)
1066 if self.
markerMove is not None: self.markerMove.setSymbol(markerMove.symbolNormal)
1070 hPlot.canvas().setMouseTracking(
False)
1073 self.moveKnob.setVisible(
True)
1074 self.moveKnob.setValue( markerMove.x )
1076 st =
'To move marker: Drag the mouse, use Left-arrow or Right-arrow keys, or use the bottom slider. Quit moving with Right-Click or Esc key.'
1077 self.statusBar.showMessage(st)
1078 hPlot.setStatusTip(st)
1088 nTab = self.tabWidget.currentIndex()
1089 self.
hPlot[nTab].canvas().setMouseTracking(
True)
1092 if self.
markerMove is not None: self.markerMove.setSymbol(self.markerMove.symbolNormal)
1094 self.moveKnob.setVisible(
False)
1095 self.
hPlot[nTab].replot()
1097 st =
u'Left-click in a marker to move, Right-Click or Esc key to quit'
1098 self.statusBar.showMessage(st)
1099 self.
hPlot[nTab].setStatusTip(st)
1108 if not self.actionMoveMarker.isChecked():
return
1114 N = len(marker.curve.data().xData())
1115 newindex = marker.index + increment
1116 if newindex < 0: newindex= 0
1117 if newindex > N-1: newindex = N-1
1119 marker.index = newindex
1120 marker.updatePosition()
1121 self.moveKnob.setValue(marker.x)
1130 if not self.actionMoveMarker.isChecked():
return
1133 nTab = self.tabWidget.currentIndex()
1134 hPlot = self.
hPlot[nTab]
1135 value = hPlot.invTransform(Qwt.QwtPlot.xBottom, point.x())
1143 curve = marker.curve
1144 N = len(curve.data().xData())
1145 maxValue = curve.x(N-1)
1146 minValue = curve.x(0)
1147 marker.index = int(round( (N-1) * (value - minValue) / (maxValue - minValue) ))
1149 marker.updatePosition()
1150 self.moveKnob.setValue(marker.x)
1161 if not self.actionNewMarker.isChecked():
return
1163 nTab = self.tabWidget.currentIndex()
1164 hPlot = self.
hPlot[nTab]
1166 scX, scY = point.x(), point.y()
1176 if not CF.visible:
continue
1178 for curve
in CF.curveList:
1179 n, dist = curve.closestPoint(QPoint(scX, scY))
1184 axis= Qwt.QwtPlot.yLeft
1187 if not CF.visible:
continue
1189 for curve
in CF.curveList:
1190 n, dist = curve.closestPoint(QPoint(scX, scY))
1195 axis= Qwt.QwtPlot.yRight
1198 QMessageBox.warning(self,
"WARNING",
'There is not curve point within zoomed area. No marker added.')
1203 if minDist > distThreshold:
1204 QMessageBox.warning(self,
"WARNING",
'No curve point selected.')
1207 Marker =
PlotMarker(self, axis, nTab, curveMarker, nMarker)
1208 Marker.attach(hPlot)
1210 self.
markers[nTab].append(Marker)
1235 maxScale = self.
hPlot[nTab].axisScaleDiv(axis).upperBound()
1236 minScale = self.
hPlot[nTab].axisScaleDiv(axis).lowerBound()
1237 except AttributeError:
1238 maxScale = self.
hPlot[nTab].axisScaleDiv(axis).hBound()
1239 minScale = self.
hPlot[nTab].axisScaleDiv(axis).lBound()
1241 return maxScale, minScale
1253 if axis
is Qwt.QwtPlot.yLeft:
1254 maxScale = self.
scalingDlg[nTab].leftYmax_Counter.value()
1255 minScale = self.
scalingDlg[nTab].leftYmin_Counter.value()
1256 elif axis
is Qwt.QwtPlot.yRight:
1257 maxScale = self.
scalingDlg[nTab].rightYmax_Counter.value()
1258 minScale = self.
scalingDlg[nTab].rightYmin_Counter.value()
1259 elif axis
is Qwt.QwtPlot.xBottom:
1260 maxScale = self.
scalingDlg[nTab].Xmax_Counter.value()
1261 minScale = self.
scalingDlg[nTab].Xmin_Counter.value()
1263 return maxScale, minScale
1273 leftYmax, leftYmin = self.
getScaleMaxMin(nTab, Qwt.QwtPlot.yLeft)
1278 self.
precX[nTab] = minPrec + int(ceil(log10(abs(Xmax))) - ceil(log10(abs(Xmax-Xmin))))
1280 self.
precX[nTab] = minPrec
1283 self.
precY[nTab] = minPrec + int(ceil(log10(abs(leftYmax))) - ceil(log10(abs(leftYmax-leftYmin))))
1285 self.
precY[nTab] = minPrec
1288 for marker
in self.
markers[nTab]: marker.updateLabel()
1298 nTab = self.tabWidget.currentIndex()
1300 self.moveKnob.setRange(Xmin, Xmax)
1321 oldTab = self.tabWidget.currentIndex()
1322 self.tabWidget.setCurrentIndex(nTab)
1324 if type(leftYVisible).__name__ ==
'list':
1325 for CF, flag
in zip( self.
leftYCurves[nTab], leftYVisible ):
1326 if flag
is None:
continue
1328 CF.legendItem.setChecked(flag)
1329 for k, v
in self.
setCurves[nTab].curvesCheckBoxesDict.items():
1330 if v == CF: k.setChecked(flag)
1331 elif type(leftYVisible).__name__ ==
'dict':
1332 for (name, flag)
in leftYVisible.items():
1333 if flag
is None or name
not in self.
leftYNames[nTab]:
continue
1336 CF.legendItem.setChecked(flag)
1337 for k, v
in self.
setCurves[nTab].curvesCheckBoxesDict.items():
1338 if v == CF: k.setChecked(flag)
1340 if type(rightYVisible).__name__ ==
'list':
1341 for CF, flag
in zip( self.
rightYCurves[nTab], rightYVisible ):
1342 if flag
is None:
continue
1344 CF.legendItem.setChecked(flag)
1345 for k, v
in self.
setCurves[nTab].curvesCheckBoxesDict.items():
1346 if v == CF: k.setChecked(flag)
1347 elif type(rightYVisible).__name__ ==
'dict':
1348 for (name, flag)
in rightYVisible.items():
1349 if flag
is None or name
not in self.
rightYNames[nTab]:
continue
1352 CF.legendItem.setChecked(flag)
1353 for k, v
in self.
setCurves[nTab].curvesCheckBoxesDict.items():
1354 if v == CF: k.setChecked(flag)
1356 if type(masksVisible).__name__ ==
'list':
1357 for curve, flag
in zip( self.
masks[nTab], masksVisible ):
1358 if flag
is None:
continue
1359 curve.setVisible(flag)
1360 self.
legends[nTab].find(curve).setChecked(flag)
1361 for k, v
in self.
setCurves[nTab].curvesCheckBoxesDict.items():
1362 if v == curve: k.setChecked(flag)
1363 elif type(masksVisible).__name__ ==
'dict':
1364 for (name, flag)
in masksVisible.items():
1365 if flag
is None or name
not in self.
maskNames[nTab]:
continue
1367 curve.setVisible(flag)
1368 self.
legends[nTab].find(curve).setChecked(flag)
1369 for k, v
in self.
setCurves[nTab].curvesCheckBoxesDict.items():
1370 if v == curve: k.setChecked(flag)
1373 self.
hPlot[nTab].replot()
1374 self.tabWidget.setCurrentIndex(oldTab)
1389 if autoScaleBottomX:
1391 (axisMin, axisMax) = ( zoomerBase.Xmin, zoomerBase.Xmax )
1392 if axisMin != np.inf
and axisMax != -np.inf: self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.xBottom, axisMin, axisMax )
1393 self.
scalingDlg[nTab].X_groupBox.setChecked(
False)
1397 (axisMin, axisMax) = ( zoomerBase.leftYmin, zoomerBase.leftYmax )
1398 if axisMin != np.inf
and axisMax != -np.inf: self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.yLeft, axisMin, axisMax )
1399 self.
scalingDlg[nTab].leftY_groupBox.setChecked(
False)
1403 (axisMin, axisMax) = ( zoomerBase.rightYmin, zoomerBase.rightYmax )
1404 if axisMin != np.inf
and axisMax != -np.inf: self.
hPlot[nTab].setAxisScale( Qwt.QwtPlot.yRight, axisMin, axisMax )
1405 self.
scalingDlg[nTab].rightY_groupBox.setChecked(
False)
1408 self.
hPlot[nTab].replot()
1414 @pyqtSignature(
"double")
1422 if not self.actionMoveMarker.isChecked():
return
1424 nTab = self.tabWidget.currentIndex()
1431 curve = self.markerMove.curve
1432 N = len(curve.data().xData())
1433 maxValue = curve.x(N-1)
1434 minValue = curve.x(0)
1435 self.markerMove.index = int(round( (N-1) * (value - minValue) / (maxValue - minValue) ))
1437 self.markerMove.updatePosition()
1438 self.
hPlot[nTab].replot()
1449 nTab = self.tabWidget.currentIndex()
1450 CF = self.
setCurves[nTab].curvesCheckBoxesDict[self.sender()]
1454 for curve
in CF.curveList:
1455 for marker
in self.
markers[nTab]:
1456 if marker.curve == curve: marker.setVisible(on)
1459 CF.legendItem.setChecked(on)
1461 self.
hPlot[nTab].replot()
1471 nTab = self.tabWidget.currentIndex()
1472 CF = self.
setCurves[nTab].curvesSpinBoxesDict[self.sender()]
1476 self.
hPlot[nTab].replot()
1486 nTab = self.tabWidget.currentIndex()
1487 CF = self.
setCurves[nTab].curvesPushButtonsDict[self.sender()]
1489 newColor = QColorDialog().getColor(pen.color())
1490 palette = self.sender().palette()
1491 palette.setColor(QPalette.Button, newColor)
1492 self.sender().setPalette(palette)
1493 pen.setColor(newColor)
1495 self.
hPlot[nTab].replot()
1504 nTab = self.tabWidget.currentIndex()
1508 for k, CF
in self.
setCurves[nTab].curvesCheckBoxesDict.items():
1509 if CF.curveList[0] == item: k.setChecked(on)
1511 self.
hPlot[nTab].replot()
1520 nTab = self.tabWidget.currentIndex()
1522 self.
hPlot[nTab].setAxisScale(axis, minScale, maxScale)
1524 self.
hPlot[nTab].replot()
1534 nTab = self.tabWidget.currentIndex()
1543 self.
hPlot[nTab].replot()
1553 nTab = self.tabWidget.currentIndex()
1554 groupBox.setChecked(
False)
1557 if axis == Qwt.QwtPlot.yLeft: (axisMin, axisMax) = ( zoomerBase.leftYmin, zoomerBase.leftYmax )
1558 if axis == Qwt.QwtPlot.yRight: (axisMin, axisMax) = ( zoomerBase.rightYmin, zoomerBase.rightYmax )
1559 if axis == Qwt.QwtPlot.xBottom: (axisMin, axisMax) = ( zoomerBase.Xmin, zoomerBase.Xmax )
1561 if axisMin != np.inf
and axisMax != -np.inf: self.
hPlot[nTab].setAxisScale( axis, axisMin, axisMax )
1563 self.
hPlot[nTab].replot()
1566 @pyqtSignature(
"int")
1573 nTab = self.tabWidget.currentIndex()
1575 if nTab >= len(self.
hPlot):
return
1582 geom = self.scalingDlgCurrent.geometry()
1583 self.scalingDlgCurrent.hide()
1585 self.scalingDlgCurrent.setGeometry(geom)
1594 self.actionCurves.setChecked(
False)
1598 self.actionCurves.setEnabled(
True)
1600 self.actionCurves.setEnabled(
False)
1603 @pyqtSignature(
"bool")
1610 nTab = self.tabWidget.currentIndex()
1612 printer = QPrinter(QPrinter.HighResolution)
1614 printer.setOrientation(QPrinter.Landscape)
1615 printer.setColorMode(QPrinter.Color)
1617 dialog = QPrintDialog(printer)
1620 if (QPrinter.GrayScale == printer.colorMode()):
1621 filter.setOptions(QwtPlotPrintFilter.PrintAll & ~QwtPlotPrintFilter.PrintBackground | QwtPlotPrintFilter.PrintFrameWithScales)
1622 self.
hPlot[nTab].print_(printer, filter)
1625 @pyqtSignature(
"bool")
1634 st = st.replace(
'@package',
'Package:')
1635 st = st.replace(
'@author',
'Authors:')
1636 st = st.replace(
'@date',
'Date:')
1637 st = st.replace(
'@version',
'Version:')
1641 <p>Software versions:
1642 <p>Python %s - Qt %s - PyQt %s - QWT %s on %s %s""" % (applicationName, st, platform.python_version(),QT_VERSION_STR, PYQT_VERSION_STR, Qwt.QWT_VERSION_STR, platform.system(), platform.release())
1644 QMessageBox.about(self,
"About %s" % applicationName, st)
1647 @pyqtSignature(
"bool")
1654 nTab = self.tabWidget.currentIndex()
1656 if QT_VERSION > 0x040100:
1657 fileName = QFileDialog.getSaveFileName(self,
1658 'Export File Name',
'dbPlot.pdf',
'PDF Documents (*.pdf)')
1660 if not fileName.isEmpty():
1661 printer = QPrinter()
1662 printer.setOutputFormat(QPrinter.PdfFormat)
1663 printer.setOrientation(QPrinter.Landscape)
1664 printer.setOutputFileName(fileName)
1666 printer.setCreator(
'lossyfiltersgui')
1667 self.
hPlot[nTab].print_(printer)
1670 @pyqtSignature(
"bool")
1676 nTab = self.tabWidget.currentIndex()
1677 if nTab >= len(self.
hPlot):
return
1684 st =
u'Drag rectangle to zoom in, center-click to zoom back, shift-center-click to zoom forward, right-click to autoscale all axis'
1686 self.actionScaleAxis.setChecked(
False)
1689 self.actionNewMarker.setChecked(
False)
1690 self.actionDeleteMarker.setChecked(
False)
1691 self.actionMoveMarker.setChecked(
False)
1694 self.
scalingDlg[nTab].leftY_groupBox.setChecked(
False)
1695 self.
scalingDlg[nTab].rightY_groupBox.setChecked(
False)
1696 self.
scalingDlg[nTab].X_groupBox.setChecked(
False)
1698 self.actionZoom.setChecked(
False)
1699 st =
u'Use toolbar buttons to zoom, add or delete markers'
1701 if not self.actionNewMarker.isChecked():
1702 self.statusBar.showMessage(st)
1703 self.
hPlot[nTab].setStatusTip(st)
1706 @pyqtSignature(
"bool")
1712 nTab = self.tabWidget.currentIndex()
1715 st =
u"Left-Click in a curve point to add a marker, Right-Click in background or press 'Del' key to delete last marker "
1719 self.actionDeleteMarker.setChecked(
False)
1720 self.actionMoveMarker.setChecked(
False)
1722 self.
pickerLeft[nTab].setTrackerPen(QPen(Qt.blue))
1724 symbol = Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse,QBrush(Qt.yellow), QPen(Qt.red, 2), QSize(5, 5) )
1730 CF.setSymbol(symbol)
1733 st =
u'Use toolbar buttons to zoom, add, move or delete markers'
1734 self.actionNewMarker.setChecked(
False)
1736 self.
pickerLeft[nTab].setTrackerPen(QPen(Qt.black))
1738 symbol = Qwt.QwtSymbol(Qwt.QwtSymbol.NoSymbol,QBrush(Qt.yellow), QPen(Qt.red, 2), QSize(5, 5) )
1741 CF.setSymbol(symbol)
1744 CF.setSymbol(symbol)
1746 self.statusBar.showMessage(st)
1747 self.
hPlot[nTab].setStatusTip(st)
1748 self.
hPlot[nTab].replot()
1751 @pyqtSignature(
"bool")
1757 nTab = self.tabWidget.currentIndex()
1763 self.actionNewMarker.setChecked(
False)
1764 self.actionMoveMarker.setChecked(
False)
1766 if len(self.
markers[nTab]) == 0:
1767 QMessageBox.warning(self,
"WARNING",
'There are no markers to delete in this Tab.')
1771 self.
pickerLeft[nTab].setTrackerMode(Qwt.QwtPicker.AlwaysOff)
1772 st =
u'Left-click in a marker to delete, Right-Click or Esc key to quit.'
1774 self.
pickerLeft[nTab].setTrackerMode(Qwt.QwtPicker.AlwaysOn)
1775 self.
pickerLeft[nTab].setTrackerPen(QPen(Qt.black))
1776 st =
u'Use toolbar buttons to zoom, add, move or delete markers'
1777 self.actionDeleteMarker.setChecked(
False)
1779 self.statusBar.showMessage(st)
1780 self.
hPlot[nTab].setStatusTip(st)
1783 @pyqtSignature(
"bool")
1789 nTab = self.tabWidget.currentIndex()
1794 self.actionNewMarker.setChecked(
False)
1795 self.actionDeleteMarker.setChecked(
False)
1797 if len(self.
markers[nTab]) == 0:
1798 QMessageBox.warning(self,
"WARNING",
'There are no markers to move in this Tab.')
1802 self.
pickerLeft[nTab].setTrackerMode(Qwt.QwtPicker.AlwaysOff)
1803 st =
u'Left-click in a marker to move, Right-Click or Esc key to quit'
1811 self.
pickerLeft[nTab].setTrackerMode(Qwt.QwtPicker.AlwaysOn)
1812 self.
pickerLeft[nTab].setTrackerPen(QPen(Qt.black))
1814 self.moveKnob.setVisible(
False)
1815 self.actionMoveMarker.setChecked(
False)
1816 st =
u'Use toolbar buttons to zoom, add, move or delete markers'
1818 self.statusBar.showMessage(st)
1819 self.
hPlot[nTab].setStatusTip(st)
1822 @pyqtSignature(
"bool")
1828 nTab = self.tabWidget.currentIndex()
1829 if nTab >= len(self.
hPlot):
return
1841 @pyqtSignature(
"bool")
1847 nTab = self.tabWidget.currentIndex()
1848 if nTab >= len(self.
hPlot):
return
1876 super(AxisScalingDlg, self).
__init__(parent)
1886 nTab = self.mainWindow.tabWidget.currentIndex()
1887 self.mainWindow.scalingDlg[nTab].hide()
1888 self.mainWindow.scalingDlgCurrent =
None
1889 self.mainWindow.actionScaleAxis.setChecked(
False)
1915 def __init__(self, hPlot, name, xdata, ydata, axis, visible, color, width):
1924 if width
is not None: self.
pen = QPen(color, width)
1925 else: self.
pen = QPen(color)
1938 if type(ydata).__name__ ==
'ndarray' and ydata.ndim == 2:
1945 curve = Qwt.QwtPlotCurve(self.
name)
1946 curve.attach(self.
hPlot)
1947 if self.
Ncurves == 1: curve.setData(xdata, ydata)
1948 else: curve.setData(xdata, ydata[:, m])
1949 curve.setPen(self.
pen)
1950 curve.setYAxis(self.
axis)
1951 curve.setVisible(self.
visible)
1952 self.curveList.append(curve)
1975 if type(ydata).__name__ ==
'ndarray' and ydata.ndim == 2: Ncurves = ydata.shape[1]
1979 cfXmin, cfXmax, cfYmin, cfYmax = np.inf, -np.inf, np.inf, -np.inf
1989 for m
in range(Ncurves):
1990 if Ncurves == 1: y = ydata
1991 else: y = ydata[:, m]
1992 if not dataUpdated: self.
curveList[m].setData(xdata, y)
1994 if min(xdata) < cfXmin: cfXmin = min(xdata)
1995 if max(xdata) > cfXmax: cfXmax = max(xdata)
1996 if min(y) < cfYmin: cfYmin = min(y)
1997 if max(y) > cfYmax: cfYmax = max(y)
1999 return cfXmin, cfXmax, cfYmin, cfYmax
2041 if legend
is not None: self.
legend = legend
2047 for n, curve
in enumerate(self.
curveList):
2048 item = self.legend.find(curve)
2051 idenWidth = item.identifierWidth()
2052 item.setIdentifierWidth(2*idenWidth)
2054 if updateLegend: curve.updateLegend(self.
legend)
2056 item.setVisible(
False)
2057 layout = self.legend.contentsWidget().children()[0]
2058 layout.removeWidget(item)
2075 def __init__(self, leftYCurves, rightYCurves, parent=None):
2076 super(EditCurvesDlg, self).
__init__(parent)
2094 nTab = self.mainWindow.tabWidget.currentIndex()
2096 grid = QGridLayout()
2098 if len(leftYCurves) > 0:
2099 grid.addWidget(QLabel(
"<b>Left-Y curves</b>"), 0, 0, 1, -1, Qt.AlignHCenter)
2100 grid.addWidget(QLabel(
"Curve"), 1, 0, Qt.AlignHCenter)
2101 grid.addWidget(QLabel(
"Width"), 1, 1, Qt.AlignHCenter)
2102 grid.addWidget(QLabel(
"Color"), 1, 2, Qt.AlignHCenter)
2104 for n
in range(len(leftYCurves)):
2106 checkBox = QCheckBox(CF.name.replace(
'<sub>',
'').replace(
'</sub>',
''))
2107 checkBox.setChecked(CF.visible)
2109 self.connect(checkBox, SIGNAL(
"stateChanged(int)"), self.mainWindow.setCurveVisibility )
2110 grid.addWidget(checkBox, n+2, 0)
2111 spinBox = QSpinBox()
2112 spinBox.setMinimum(0)
2113 spinBox.setValue(CF.pen.width())
2115 self.connect(spinBox, SIGNAL(
"valueChanged(int)"), self.mainWindow.setCurveWidth )
2116 grid.addWidget(spinBox, n+2, 1)
2117 pushButton = QPushButton()
2118 palette = pushButton.palette()
2119 palette.setColor(QPalette.Button, CF.pen.color())
2120 pushButton.setPalette(palette)
2122 self.connect(pushButton, SIGNAL(
"clicked(bool)"), self.mainWindow.setCurveColor )
2123 grid.addWidget(pushButton, n+2, 2)
2127 if len(rightYCurves) > 0:
2128 grid.addWidget(QLabel(
" "), n+3, 0, 1, -1, Qt.AlignHCenter)
2129 grid.addWidget(QLabel(
"<b>Right-Y curves</b>"), n+4, 0, 1, -1, Qt.AlignHCenter)
2130 grid.addWidget(QLabel(
"Curve"), n+5, 0, Qt.AlignHCenter)
2131 grid.addWidget(QLabel(
"Width"), n+5, 1, Qt.AlignHCenter)
2132 grid.addWidget(QLabel(
"Color"), n+5, 2, Qt.AlignHCenter)
2134 for n
in range(len(rightYCurves)):
2135 CF = rightYCurves[n]
2136 Hlayout = QHBoxLayout()
2137 checkBox = QCheckBox(CF.name.replace(
'<sub>',
'').replace(
'</sub>',
''))
2138 checkBox.setChecked(CF.visible)
2140 self.connect(checkBox, SIGNAL(
"stateChanged(int)"), self.mainWindow.setCurveVisibility )
2141 grid.addWidget(checkBox, nLeft+6+n, 0)
2142 spinBox = QSpinBox()
2143 spinBox.setMinimum(0)
2144 spinBox.setValue(CF.pen.width())
2146 self.connect(spinBox, SIGNAL(
"valueChanged(int)"), self.mainWindow.setCurveWidth )
2147 grid.addWidget(spinBox, nLeft+6+n, 1)
2148 pushButton = QPushButton()
2149 palette = pushButton.palette()
2150 palette.setColor(QPalette.Button, CF.pen.color())
2151 pushButton.setPalette(palette)
2153 self.connect(pushButton, SIGNAL(
"clicked(bool)"), self.mainWindow.setCurveColor )
2154 grid.addWidget(pushButton, nLeft+6+n, 2)
2156 self.setLayout(grid)
2157 self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
2158 self.setWindowTitle(
"Curves")
2159 self.setToolTip(
"Select visible curves")
2167 self.mainWindow.actionCurves.setChecked(
False)
2184 super(MyPicker, self).
__init__(*args)
2197 if type(point).__name__ ==
"QPoint": point = self.invTransform(point)
2198 st =
'%.*g%s, %.*g%s' % (self.dbplot.precX[self.
nTab], point.x(), self.dbplot.Xunits[self.
nTab], self.dbplot.precY[self.
nTab], point.y(), self.dbplot.leftYunits[self.
nTab])
2199 return Qwt.QwtText(st)
2231 QObject.__init__(self, hPlot)
2244 if event.type() == QEvent.MouseButtonPress:
2246 if event.button() == Qt.RightButton:
2248 if self.dbplot.actionNewMarker.isChecked():
2249 if len(self.dbplot.markers[self.dbplot.tabWidget.currentIndex()]) > 0:
2250 self.dbplot.deleteLastMarker()
2252 self.dbplot.on_actionNewMarker_toggled(
False)
2255 if self.dbplot.actionDeleteMarker.isChecked():
2256 self.dbplot.on_actionDeleteMarker_toggled(
False)
2259 if self.dbplot.actionMoveMarker.isChecked():
2260 if self.dbplot.draggingMode: self.dbplot.deselectMarker()
2261 else: self.dbplot.on_actionMoveMarker_toggled(
False)
2265 if event.button() == Qt.LeftButton:
2267 if not self.dbplot.draggingMode:
2268 if self.dbplot.actionNewMarker.isChecked(): self.dbplot.addMarker(event.pos())
2269 elif self.dbplot.actionDeleteMarker.isChecked(): self.dbplot.deleteMarker(event.pos())
2270 elif self.dbplot.actionMoveMarker.isChecked(): self.dbplot.selectAndHighlightMarker(event.pos())
2276 elif event.type() == QEvent.MouseMove:
2277 if self.dbplot.draggingMode
and self.dbplot.markerMove
is not None:
2278 self.dbplot.dragMarker(event.pos())
2280 elif event.type() == QEvent.KeyPress:
2282 if event.key() == Qt.Key_Delete:
2283 if self.dbplot.actionNewMarker.isChecked(): self.dbplot.deleteLastMarker()
2286 elif event.key() == Qt.Key_Escape:
2287 if self.dbplot.actionNewMarker.isChecked():
2288 self.dbplot.on_actionNewMarker_toggled(
False)
2290 if self.dbplot.actionDeleteMarker.isChecked():
2291 self.dbplot.on_actionDeleteMarker_toggled(
False)
2293 if self.dbplot.actionMoveMarker.isChecked():
2294 if self.dbplot.draggingMode: self.dbplot.deselectMarker()
2295 else: self.dbplot.on_actionMoveMarker_toggled(
False)
2298 elif event.key() == Qt.Key_Right
and self.dbplot.actionMoveMarker.isChecked():
2299 self.dbplot.shiftMarker(1)
2302 elif event.key() == Qt.Key_Left
and self.dbplot.actionMoveMarker.isChecked():
2303 self.dbplot.shiftMarker(-1)
2306 return Qwt.QwtPlot.eventFilter(self, object, event)
2348 self.
x = curve.x(index)
2352 self.
y = curve.y(index)
2356 self.
hPlot = dbplot.hPlot[nTab]
2360 self.setValue(self.
x, self.
y)
2365 self.
symbolNormal = Qwt.QwtSymbol(Qwt.QwtSymbol.Cross,QBrush(Qt.black), QPen(Qt.black, 2), QSize(10, 10) )
2369 self.
symbolMove = Qwt.QwtSymbol(Qwt.QwtSymbol.Cross,QBrush(Qt.red), QPen(Qt.red, 3), QSize(15, 15) )
2373 self.
symbolDel = Qwt.QwtSymbol(Qwt.QwtSymbol.UTriangle,QBrush(Qt.yellow), QPen(Qt.red, 2), QSize(10, 10) )
2383 if self.
axis == Qwt.QwtPlot.yLeft:
2384 units = self.dbplot.leftYunits[self.
nTab]
2385 elif self.
axis == Qwt.QwtPlot.yRight:
2386 units = self.dbplot.rightYunits[self.
nTab]
2388 text = Qwt.QwtText(
"%.*g%s, %.*g%s" % (self.dbplot.precX[self.
nTab], self.
x, self.dbplot.Xunits[self.
nTab], self.dbplot.precY[self.
nTab], self.
y, units ) )
2392 self.setLabelAlignment(Qt.AlignRight | Qt.AlignBottom)
2400 self.
x = self.curve.x(self.
index)
2401 self.
y = self.curve.y(self.
index)
2402 self.setValue(self.
x, self.
y)
2419 def __init__(self, leftZoomerBaseRect, rightZoomerBaseRect):
2431 self.
Xmin = self.leftZoomerBaseRect.x()
2435 self.
Xmax = self.leftZoomerBaseRect.x() + self.leftZoomerBaseRect.width()
2439 self.
leftYmin = self.leftZoomerBaseRect.y()
2443 self.
leftYmax = self.leftZoomerBaseRect.y() + self.leftZoomerBaseRect.height()
2447 self.
rightYmin = self.rightZoomerBaseRect.y()
2451 self.
rightYmax = self.rightZoomerBaseRect.y() + self.rightZoomerBaseRect.height()
2469 self.
leftZoomerBaseRect = QRectF(Xmin, leftYmin, Xmax - Xmin, leftYmax - leftYmin )
if max(np.abs( [Xmin, leftYmin, Xmax, leftYmax] )) < np.inf
else None
2470 self.
rightZoomerBaseRect = QRectF(Xmin, rightYmin, Xmax - Xmin, rightYmax - rightYmin )
if max(np.abs( [Xmin, rightYmin, Xmax, rightYmax] )) < np.inf
else None
2485 Qwt.QwtPlotPrintFilter.__init__(self)
2495 if not (self.options() & Qwt.QwtPlotPrintFilter.CanvasBackground):
2496 if item == Qwt.QwtPlotPrintFilter.MajorGrid:
2498 elif item == Qwt.QwtPlotPrintFilter.MinorGrid:
2500 if item == Qwt.QwtPlotPrintFilter.CanvasBackground:
2525 if __name__ ==
'__main__':
2527 app = QApplication(sys.argv)
2528 ui =
DbPlot( [0, 1, 2, 3], [101, 52, 803, 500], XLabel =
'y-axis' , leftYLabel =
'Left axis', leftYNames = [
'Left-axis data'],
2529 rightYData = [0.3, -0.5, 0.2, 0.4], rightYLabel =
'Right axis', rightYNames = [
'Right-axis data'], rightYColors = [ Qt.red],
2530 Xunits =
'GHz', leftYunits =
'dBm',
2531 windowTitle =
'Example', tabTitle =
'Single-curve', title =
'1 curve (list)', textLabel =
'A two-line\ntext label')
2534 x = np.arange(np.pi/N, np.pi, np.pi / N )
2535 ly1 = 10*np.log10(np.sin(x))
2536 ly2 = 10*np.log10(np.abs(np.cos(x)))
2537 ly2[ly2 < -10] = -10
2538 ry1 = 10*np.log10(np.sinh(x))
2539 ry2 = 10*np.log10(np.cosh(x))
2540 ui.addTab( 180*x/np.pi, [ ly1, ly2], XLabel =
'x' , leftYNames = [
'Sin(x)',
'|Cos(x)|'], leftYLabel =
'Trigonometric values (dB)',
2541 rightYData = [ ry1, ry2 ], rightYLabel =
'Hyperbolic values (dB)', rightYNames = [
'Sinh(x)',
'Cosh(x)'], rightYColors = [ Qt.cyan, Qt.green],
2542 Xunits =
'rad', leftYunits =
'dB', leftWidth = [2, 2], rightWidth = [2, 2],
2543 tabTitle =
'Multi-curve', title =
'2 curves (numpy arrays) with masks', leftYVisible = [
True,
False], rightYVisible = [
False,
True])
2545 mask = np.array( [ (20, -4), (60, -2), (85, -0.5), (90, -0.4), (95, -0.5), (120, -2), (160, -4) ] )
2546 ui.addMask(nTab = 1, XData = mask[:, 0], YData = mask[:, 1], axis =
'left', name =
'Lower Mask', color = Qt.blue, type =
'Lower', transpar = 32 )
2548 mask = np.array( [ (40, -2), (80, -5), (80, np.nan), (100, np.nan), (100, -5), (140, -2) ] )
2549 ui.addMask(nTab = 1, XData = mask[:, 0], YData = mask[:, 1], axis =
'left', name =
'Upper Mask', color = Qt.red, type =
'Upper', transpar = 32)
2551 mask = np.array([ (50, 0), (100, 4), (150, 8) ])
2552 ui.addMask(nTab = 1, XData = mask[:, 0], YData = mask[:, 1], axis =
'right', name =
'Right lower Mask', color = Qt.green, type =
'Lower', transpar = 64)
2556 ui.addTab( XData = [[0, 1, 2, 3], [0.5, 1.5, 2.5, 3.5, 4.5]], leftYData = [ [20, 10, 1, 0], [3, 5, -2, 4, 1] ], leftYNames = [
'width=2',
'width=3'], leftYLabel =
'Left axis',
2557 rightXData = [2.5, 3.5, 4.5, 5.5], rightYData = [ 25, 35, 45, 55], rightYNames =
'width=4', rightYLabel =
'Right-y axis',
2558 leftWidth = [2, 3], rightWidth = 4,
2559 tabTitle =
'Multi-axis', title =
'Example with different x-axis data for each curve, and manual scaling', Xmin = 1, Xmax = 5, leftYmin = 0, rightYmax = 50)
2561 ui.addTab( XData = np.array([0, 1, 2, 3]), leftYData = [ np.array([5, 10, 1, 0]), np.array([[6, 9, 3, 2], [6.2, 9.2, 3.2, 2.2], [6.4, 9.4, 3.4, 2.4]]).T ], leftYNames = [
'1-D array Left',
'2-D array Left' ], leftYLabel =
'Left axis',
2562 rightXData = np.array([0.5, 1.5, 2.5, 3.5]), rightYData = np.array([[ 25, 5, 15, 35], [25.4, 5.4, 15.4, 35.4], [25.8, 5.8, 15.8, 35.8]]).T, rightYNames =
'2-D array Right', rightYLabel =
'Right-y axis',
2563 tabTitle =
'Numpy arrays', title =
'Example with data in 2-D numpy arrays')
2565 ui.addTab( XData = np.array([0, 1, 2, 3]), leftYData = np.array([[6, 9, 3, 2], [6.2, 9.2, 3.2, 2.2], [6.4, 9.4, 3.4, 2.4]]).T, leftYNames =
'2-D array Left' , leftYLabel =
'Left axis',
2566 tabTitle =
'Left-Y only', title =
'Example with data in left-Y axis only')
2568 ui.addTab( XData = [0, 1], leftYData = [ [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9] ],
2569 tabTitle =
'Multi-color', title =
'Example with many curves of different colors',
2570 leftYVisible = [
True,
True,
True,
True,
True,
True,
True,
True ])
2572 ui.update(5, XData = [0, 10], leftYData = [ [10.35, 20], [20, 30], [30, 40], [40, 50], [50, 60], [60, 70], [70, 80], [80, 90.14] ])
2573 ui.autoScaleSomeAxis(5, autoScaleBottomX =
True, autoScaleLeftY =
True, autoScaleRightY =
False)
2575 ui.addTab( 1.1*180*x/np.pi, [ 1.1*ly1, 1.1*ly2], XLabel =
'x' , leftYNames = [
'Sin(x) 1.1',
'|Cos(x)| 1.1'], leftYLabel =
'Trigonometric values (dB) 1.1',
2576 rightYData = [ 1.1*ry1, 1.1*ry2 ], rightYLabel =
'Hyperbolic values (dB) 1.1', rightYNames = [
'Sinh(x) 1.1',
'Cosh(x) 1.1'], rightYColors = [ Qt.cyan, Qt.green],
2577 Xunits =
'rad 1.1', leftYunits =
'dB 1.1', leftWidth = [2, 2], rightWidth = [2, 2],
2578 tabTitle =
'Multi-curve 1.1', title =
'2 curves (numpy arrays) with masks 1.1', leftYVisible = [
True,
False], rightYVisible = [
False,
True],
2581 ui.addTab( XData = [[0, 10, 20, 30, 40], [5, 15, 25, 35, 45, 55]], leftYData = [ [200, 100, 10, 0, 50], [30, 50, -20, 40, 10, -30] ], leftYNames = [
'width10=2',
'width10=3'], leftYLabel =
'Left axis 10',
2582 rightXData = [25, 35, 45, 55, 65], rightYData = [ 2500, 3500, 4500, 5500, 4500], rightYNames =
'width10=4', rightYLabel =
'Right-y axis 10',
2583 leftWidth = [2, 3], rightWidth = 4,
2584 tabTitle =
'Multi-axis 10', title =
'Example of replaceTab', Xmin = 10, Xmax = 60, leftYmin = 0, rightYmax = 5000,
2587 ui.addTab( XData = 10*np.array([0, 1, 2, 3]), leftYData = [ 10*np.array([5, 10, 1, 0]), 10*np.array([[6, 9, 3, 2], [6.2, 9.2, 3.2, 2.2], [6.4, 9.4, 3.4, 2.4]]).T ], leftYNames = [
'1-D array Left 10',
'2-D array Left 10' ], leftYLabel =
'Left axis 10',
2588 rightXData = 10*np.array([0.5, 1.5, 2.5, 3.5]), rightYData = 10*np.array([[ 25, 5, 15, 35], [25.4, 5.4, 15.4, 35.4], [25.8, 5.8, 15.8, 35.8]]).T, rightYNames =
'2-D array Right 10', rightYLabel =
'Right-y axis 10',
2589 tabTitle =
'Numpy arrays 10', title =
'Example of replace Tab with 2-D numpy arrays',