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

1#!/usr/bin/env python 

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

3 

4""" 

5Custom version of SILX Plot1D 

6============================= 

7 

8This class is based on: 

9 

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 

12 

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 

20 

21 

22class CustomCurveLegendsWidget(CurveLegendsWidget): 

23 """Extension of CurveLegendWidget. 

24 

25 .. note:: Taken from SILX examples -> plotCurveLegendWidget 

26 

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 """ 

32 

33 def __init__(self, parent=None): 

34 super(CustomCurveLegendsWidget, self).__init__(parent) 

35 

36 # Activate/Deactivate curve with left click on the legend widget 

37 self.sigCurveClicked.connect(self._switchCurveActive) 

38 

39 # Add a custom context menu 

40 self.setContextMenuPolicy(qt.Qt.CustomContextMenu) 

41 self.customContextMenuRequested.connect(self._contextMenu) 

42 

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) 

51 

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()) 

57 

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') 

64 

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) 

70 

71 def _clearPlot(self, plot): 

72 """Clear plot""" 

73 plot.clear() 

74 

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 

82 

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)) 

87 

88 # Add an action to show/hide the curve 

89 menu.addAction('Hide' if curve.isVisible() else 'Show', 

90 functools.partial(self._switchCurveVisibility, curve)) 

91 

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)) 

95 

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)) 

100 

101 menu.addSeparator() 

102 

103 # Add an action to clear the plot 

104 plot = curve.getPlot() 

105 menu.addAction('Clear plot', functools.partial(self._clearPlot, plot)) 

106 

107 globalPosition = self.mapToGlobal(pos) 

108 menu.exec_(globalPosition) 

109 

110 

111class Plot1D(PlotWindow): 

112 """Custom PlotWindow instance targeted to 1D curves""" 

113 

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) 

127 

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) 

131 

132 self.setDataMargins(0, 0, 0.05, 0.05) 

133 

134 # Create a MyCurveLegendWidget associated to the plot 

135 self.legendsWidget = CustomCurveLegendsWidget() 

136 self.legendsWidget.setPlotWidget(self) 

137 

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) 

143 

144 # Show the plot and run the QApplication 

145 self.setAttribute(qt.Qt.WA_DeleteOnClose) 

146 

147 def index(self): 

148 if self._index is None: 

149 self._index = 0 

150 return self._index 

151 

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)) 

156 

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) 

164 

165 

166def main(): 

167 """Run a Qt app with the widget""" 

168 app = qt.QApplication([]) 

169 widget = Plot1D() 

170 widget.show() 

171 app.exec_() 

172 

173 

174if __name__ == '__main__': 

175 main()