Coverage for /Users/Newville/Codes/xraylarch/larch/qtlib/plot1D.py: 0%
78 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
4"""
5Custom version of SILX Plot1D
6=============================
8This class is based on:
10- https://github.com/mretegan/crispy/blob/master/crispy/gui/widgets/plotwidget.py
11- https://github.com/silx-kit/silx/blob/master/examples/plotCurveLegendWidget.py
13"""
14from __future__ import absolute_import, division, unicode_literals
15import functools
16from silx.gui import qt
17from silx.gui.plot import PlotWindow
18from silx.gui.plot.tools.CurveLegendsWidget import CurveLegendsWidget
19from silx.gui.widgets.BoxLayoutDockWidget import BoxLayoutDockWidget
22class CustomCurveLegendsWidget(CurveLegendsWidget):
23 """Extension of CurveLegendWidget.
25 .. note:: Taken from SILX examples -> plotCurveLegendWidget
27 This widget adds:
28 - Set a curve as active with a left click its the legend
29 - Adds a context menu with content specific to the hovered legend
30 :param QWidget parent: See QWidget
31 """
33 def __init__(self, parent=None):
34 super(CustomCurveLegendsWidget, self).__init__(parent)
36 # Activate/Deactivate curve with left click on the legend widget
37 self.sigCurveClicked.connect(self._switchCurveActive)
39 # Add a custom context menu
40 self.setContextMenuPolicy(qt.Qt.CustomContextMenu)
41 self.customContextMenuRequested.connect(self._contextMenu)
43 def _switchCurveActive(self, curve):
44 """Set a curve as active.
45 This is called from the context menu and when a legend is clicked.
46 :param silx.gui.plot.items.Curve curve:
47 """
48 plot = curve.getPlot()
49 plot.setActiveCurve(
50 curve.getLegend() if curve != plot.getActiveCurve() else None)
52 def _switchCurveVisibility(self, curve):
53 """Toggle the visibility of a curve
54 :param silx.gui.plot.items.Curve curve:
55 """
56 curve.setVisible(not curve.isVisible())
58 def _switchCurveYAxis(self, curve):
59 """Change the Y axis a curve is attached to.
60 :param silx.gui.plot.items.Curve curve:
61 """
62 yaxis = curve.getYAxis()
63 curve.setYAxis('left' if yaxis == 'right' else 'right')
65 def _copyCurve(self, curve, plot):
66 """Copy curve"""
67 data = curve.getData()
68 legend = curve.getLegend() + '*'
69 plot.addCurve(data[0], data[1], legend=legend)
71 def _clearPlot(self, plot):
72 """Clear plot"""
73 plot.clear()
75 def _contextMenu(self, pos):
76 """Create a show the context menu.
77 :param QPoint pos: Position in this widget
78 """
79 curve = self.curveAt(pos) # Retrieve curve from hovered legend
80 if curve is not None:
81 menu = qt.QMenu() # Create the menu
83 # Add an action to activate the curve
84 activeCurve = curve.getPlot().getActiveCurve()
85 menu.addAction('Unselect' if curve == activeCurve else 'Select',
86 functools.partial(self._switchCurveActive, curve))
88 # Add an action to show/hide the curve
89 menu.addAction('Hide' if curve.isVisible() else 'Show',
90 functools.partial(self._switchCurveVisibility, curve))
92 # Add an action to store a copy of the curve
93 plot = curve.getPlot()
94 menu.addAction('Copy', functools.partial(self._copyCurve, curve, plot))
96 # Add an action to switch the Y axis of a curve
97 yaxis = 'right' if curve.getYAxis() == 'left' else 'left'
98 menu.addAction('Map to %s' % yaxis,
99 functools.partial(self._switchCurveYAxis, curve))
101 menu.addSeparator()
103 # Add an action to clear the plot
104 plot = curve.getPlot()
105 menu.addAction('Clear plot', functools.partial(self._clearPlot, plot))
107 globalPosition = self.mapToGlobal(pos)
108 menu.exec_(globalPosition)
111class Plot1D(PlotWindow):
112 """Custom PlotWindow instance targeted to 1D curves"""
114 def __init__(self, parent=None, backend=None, title='Plot1D'):
115 """Constructor"""
116 super(Plot1D, self).__init__(parent=parent, backend=backend,
117 resetzoom=True, autoScale=True,
118 logScale=True, grid=False,
119 curveStyle=True, colormap=False,
120 aspectRatio=False, yInverted=False,
121 copy=True, save=True, print_=True,
122 control=False, position=True, roi=False,
123 mask=False, fit=True)
124 self._index = None
125 self._title = title
126 self.setWindowTitle(self._title)
128 # Active curve behaviour
129 # TODO: https://github.com/silx-kit/silx/blob/5035be343dc37ef60eab114c139016ebd9832d96/silx/gui/plot/test/testPlotWidget.py#L636
130 self.setActiveCurveHandling(True)
132 self.setDataMargins(0, 0, 0.05, 0.05)
134 # Create a MyCurveLegendWidget associated to the plot
135 self.legendsWidget = CustomCurveLegendsWidget()
136 self.legendsWidget.setPlotWidget(self)
138 # Add the CurveLegendsWidget as a dock widget to the plot
139 self.dock = BoxLayoutDockWidget()
140 self.dock.setWindowTitle('Legend (right click for menu)')
141 self.dock.setWidget(self.legendsWidget)
142 self.addDockWidget(qt.Qt.RightDockWidgetArea, self.dock)
144 # Show the plot and run the QApplication
145 self.setAttribute(qt.Qt.WA_DeleteOnClose)
147 def index(self):
148 if self._index is None:
149 self._index = 0
150 return self._index
152 def setIndex(self, value):
153 self._index = value
154 if self._index is not None:
155 self.setWindowTitle('{0}: {1}'.format(self._index, self._title))
157 def reset(self):
158 self.clear()
159 self.setGraphTitle()
160 self.setGraphXLabel('X')
161 # self.setGraphXLimits(0, 100)
162 self.setGraphYLabel('Y')
163 # self.setGraphYLimits(0, 100)
166def main():
167 """Run a Qt app with the widget"""
168 app = qt.QApplication([])
169 widget = Plot1D()
170 widget.show()
171 app.exec_()
174if __name__ == '__main__':
175 main()