summaryrefslogtreecommitdiff
path: root/examples/compareBackends.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/compareBackends.py')
-rw-r--r--examples/compareBackends.py375
1 files changed, 375 insertions, 0 deletions
diff --git a/examples/compareBackends.py b/examples/compareBackends.py
new file mode 100644
index 0000000..7bd8758
--- /dev/null
+++ b/examples/compareBackends.py
@@ -0,0 +1,375 @@
+# /*##########################################################################
+#
+# Copyright (c) 2017-2021 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+
+"""
+This script compares the rendering of PlotWidget's matplotlib and OpenGL backends.
+"""
+
+from __future__ import annotations
+
+__license__ = "MIT"
+
+import numpy
+import sys
+import functools
+
+from silx.gui import qt
+
+from silx.gui.plot import PlotWidget
+from silx.gui.plot import items
+from silx.gui.plot.items.marker import Marker
+from silx.gui.plot.utils.axis import SyncAxes
+
+
+_DESCRIPTIONS = {}
+
+
+class MyPlotWindow(qt.QMainWindow):
+ """QMainWindow with selected tools"""
+
+ def __init__(self, parent=None):
+ super(MyPlotWindow, self).__init__(parent)
+
+ # Create a PlotWidget
+ self._plot1 = PlotWidget(parent=self, backend="mpl")
+ self._plot1.setGraphTitle("matplotlib")
+ self._plot2 = PlotWidget(parent=self, backend="opengl")
+ self._plot2.setGraphTitle("opengl")
+
+ self.constraintX = SyncAxes(
+ [
+ self._plot1.getXAxis(),
+ self._plot2.getXAxis(),
+ ]
+ )
+ self.constraintY = SyncAxes(
+ [
+ self._plot1.getYAxis(),
+ self._plot2.getYAxis(),
+ ]
+ )
+
+ plotWidget = qt.QWidget(self)
+ plotLayout = qt.QHBoxLayout(plotWidget)
+ plotLayout.addWidget(self._plot1)
+ plotLayout.addWidget(self._plot2)
+ plotLayout.setContentsMargins(0, 0, 0, 0)
+ plotLayout.setContentsMargins(0, 0, 0, 0)
+
+ options = self.createOptions(self)
+ centralWidget = qt.QWidget(self)
+ layout = qt.QHBoxLayout(centralWidget)
+ layout.setSpacing(0)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.addWidget(options)
+ layout.addWidget(plotWidget)
+
+ self.setCentralWidget(centralWidget)
+
+ self._state = {}
+
+ def clear(self):
+ self._state = {}
+
+ def createOptions(self, parent):
+ options = qt.QWidget(parent)
+ layout = qt.QVBoxLayout(options)
+ for id, description in _DESCRIPTIONS.items():
+ label, _func = description
+ button = qt.QPushButton(label, self)
+ button.clicked.connect(functools.partial(self.showUseCase, id))
+ layout.addWidget(button)
+ layout.addStretch()
+ return options
+
+ def showUseCase(self, name: str):
+ description = _DESCRIPTIONS.get(name)
+ if description is None:
+ raise ValueError(f"Unknown use case '{name}'")
+ setupFunc = description[1]
+ self.clear()
+ for p in [self._plot1, self._plot2]:
+ p.clear()
+ setupFunc(self, p)
+ p.resetZoom()
+
+ def _register(name, label):
+ def decorator(func):
+ _DESCRIPTIONS[name] = (label, func)
+ return func
+
+ return decorator
+
+ def _addLine(
+ self,
+ plot,
+ lineWidth: float,
+ lineStyle: str,
+ color: str,
+ gapColor: str | None,
+ curve: bool,
+ ):
+ state = self._state.setdefault(plot, {})
+ x = state.get("x", 0)
+ y = state.get("y", 0)
+ x += 10
+ state["x"] = x
+ state["y"] = y
+
+ start = (x - 20, y + 0)
+ stop = (x + 40, y + 100)
+
+ def createShape():
+ shape = items.Shape("polylines")
+ shape.setPoints(numpy.array((start, stop)))
+ shape.setLineWidth(lineWidth)
+ shape.setLineStyle(lineStyle)
+ shape.setColor(color)
+ if gapColor is not None:
+ shape.setLineGapColor(gapColor)
+ return shape
+
+ def createCurve():
+ curve = items.Curve()
+ array = numpy.array((start, stop)).T
+ curve.setData(array[0], array[1])
+ curve.setLineWidth(lineWidth)
+ curve.setLineStyle(lineStyle)
+ curve.setColor(color)
+ curve.setSymbol("")
+ if gapColor is not None:
+ curve.setLineGapColor(gapColor)
+ return curve
+
+ if curve:
+ plot.addItem(createCurve())
+ else:
+ plot.addItem(createShape())
+
+ @_register("linewidth", "Line width")
+ def _setupLineStyle(self, plot: PlotWidget):
+ self._addLine(plot, 0.5, "-", "#0000FF", None, curve=False)
+ self._addLine(plot, 1.0, "-", "#0000FF", None, curve=False)
+ self._addLine(plot, 2.0, "-", "#0000FF", None, curve=False)
+ self._addLine(plot, 4.0, "-", "#0000FF", None, curve=False)
+ self._addLine(plot, 0.5, "-", "#00FFFF", None, curve=True)
+ self._addLine(plot, 1.0, "-", "#00FFFF", None, curve=True)
+ self._addLine(plot, 2.0, "-", "#00FFFF", None, curve=True)
+ self._addLine(plot, 4.0, "-", "#00FFFF", None, curve=True)
+
+ @_register("linestyle", "Line style")
+ def _setupLineStyle(self, plot: PlotWidget):
+ self._addLine(plot, 1.0, "--", "#0000FF", None, curve=False)
+ self._addLine(plot, 1.0, "-.", "#0000FF", None, curve=False)
+ self._addLine(plot, 1.0, ":", "#0000FF", None, curve=False)
+ self._addLine(plot, 2.0, "--", "#00FFFF", None, curve=True)
+ self._addLine(plot, 2.0, "-.", "#00FFFF", None, curve=True)
+ self._addLine(plot, 2.0, ":", "#00FFFF", None, curve=True)
+
+ @_register("gapcolor", "LineStyle Gap Color")
+ def _setupLineStyleGapColor(self, plot):
+ self._addLine(plot, 1.0, "-", "#FF00FF", "black", curve=False)
+ self._addLine(plot, 1.0, "-.", "#FF00FF", "black", curve=False)
+ self._addLine(plot, 1.0, "--", "#FF00FF", "black", curve=False)
+ self._addLine(plot, 0.5, "--", "#FF00FF", "black", curve=False)
+ self._addLine(plot, 1.5, "--", "#FF00FF", "black", curve=False)
+ self._addLine(plot, 2.0, "--", "#FF00FF", "black", curve=False)
+ plot.setGraphXLimits(0, 100)
+ plot.setGraphYLimits(0, 100)
+
+ @_register("curveshape", "Curve vs Shape")
+ def _setupLineStyleCurveShape(self, plot):
+ self._addLine(plot, 1.0, (0, (5, 5)), "#00FF00", None, curve=False)
+ self._addLine(plot, 4.0, (0, (3, 3)), "#00FF00", None, curve=False)
+ self._addLine(plot, 4.0, (0, (5, 5)), "#00FF00", None, curve=False)
+ self._addLine(plot, 4.0, (0, (7, 7)), "#00FF00", None, curve=False)
+ self._addLine(plot, 1.0, (0, (5, 5)), "#00FFFF", None, curve=True)
+ self._addLine(plot, 4.0, (0, (3, 3)), "#00FFFF", None, curve=True)
+ self._addLine(plot, 4.0, (0, (5, 5)), "#00FFFF", None, curve=True)
+ self._addLine(plot, 4.0, (0, (7, 7)), "#00FFFF", None, curve=True)
+ plot.setGraphXLimits(0, 100)
+ plot.setGraphYLimits(0, 100)
+
+ @_register("text", "Text")
+ def _setupText(self, plot):
+ plot.getDefaultColormap().setName("viridis")
+
+ # Add an image to the plot
+ x = numpy.outer(numpy.linspace(-10, 10, 200), numpy.linspace(-10, 5, 150))
+ image = numpy.sin(x) / x
+ plot.addImage(image)
+
+ label = Marker()
+ label.setPosition(40, 150)
+ label.setText("No background")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setPosition(50, 50)
+ label.setText("Foo bar\nmmmmmmmmmmmmmmmmmmmm")
+ label.setBackgroundColor("#FFFFFF44")
+ plot.addItem(label)
+
+ label2 = Marker()
+ label2.setPosition(70, 70)
+ label2.setText("Foo bar")
+ label2.setColor("red")
+ label2.setBackgroundColor("#00000044")
+ plot.addItem(label2)
+
+ label3 = Marker()
+ label3.setPosition(10, 70)
+ label3.setText("Pioupiou")
+ label3.setColor("yellow")
+ label3.setBackgroundColor("#000000")
+ plot.addItem(label3)
+
+ @_register("marker", "Marker")
+ def _setupMarker(self, plot):
+ plot.getDefaultColormap().setName("viridis")
+
+ # Add an image to the plot
+ x = numpy.outer(numpy.linspace(-10, 10, 200), numpy.linspace(-10, 5, 150))
+ image = numpy.sin(x) / x
+ plot.addImage(image)
+
+ label = Marker()
+ label.setSymbol("o")
+ label.setPosition(30, 30)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol(".")
+ label.setPosition(50, 30)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol(",")
+ label.setPosition(70, 30)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol("+")
+ # label.setSymbolSize(100)
+ label.setPosition(30, 50)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol("x")
+ label.setPosition(50, 50)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol("d")
+ label.setPosition(70, 50)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol("s")
+ label.setPosition(30, 70)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol("|")
+ label.setPosition(50, 70)
+ label.setColor("white")
+ plot.addItem(label)
+
+ label = Marker()
+ label.setSymbol("_")
+ label.setPosition(70, 70)
+ label.setColor("white")
+ plot.addItem(label)
+
+ @_register("arrows", "Arrows")
+ def _setupArrows(self, plot):
+ """Display few lines with markers."""
+ plot.setDataMargins(0.1, 0.1, 0.1, 0.1)
+
+ plot.addCurve(
+ x=[-10, 0, 0, -10, -10], y=[90, 90, 10, 10, 90], legend="box1", color="gray"
+ )
+ plot.addCurve(
+ x=[110, 100, 100, 110, 110],
+ y=[90, 90, 10, 10, 90],
+ legend="box2",
+ color="gray",
+ )
+ plot.addCurve(
+ y=[-10, 0, 0, -10, -10], x=[90, 90, 10, 10, 90], legend="box3", color="gray"
+ )
+ plot.addCurve(
+ y=[110, 100, 100, 110, 110],
+ x=[90, 90, 10, 10, 90],
+ legend="box4",
+ color="gray",
+ )
+
+ def addCompositeLine(
+ source, destination, symbolSource, symbolDestination, legend, color
+ ):
+ line = numpy.array([source, destination]).T
+ plot.addCurve(x=line[0, :], y=line[1, :], color=color, legend=legend)
+ plot.addMarker(x=source[0], y=source[1], symbol=symbolSource, color=color)
+ plot.addMarker(
+ x=destination[0],
+ y=destination[1],
+ symbol=symbolDestination,
+ color=color,
+ )
+
+ addCompositeLine([0, 50], [100, 50], "caretleft", "caretright", "l1", "red")
+ addCompositeLine([0, 30], [100, 30], "tickup", "tickdown", "l2", "blue")
+ addCompositeLine([0, 70], [100, 70], "|", "|", "l3", "black")
+
+ addCompositeLine([50, 0], [50, 100], "caretdown", "caretup", "l4", "red")
+ addCompositeLine([30, 0], [30, 100], "tickleft", "tickright", "l5", "blue")
+ addCompositeLine([70, 0], [70, 100], "_", "_", "l6", "black")
+
+
+def main():
+ global app
+ app = qt.QApplication([])
+
+ # Create the ad hoc window containing a PlotWidget and associated tools
+ window = MyPlotWindow()
+ window.setAttribute(qt.Qt.WA_DeleteOnClose)
+ window.show()
+ if len(sys.argv) == 1:
+ useCase = "linestyle"
+ else:
+ useCase = sys.argv[1]
+ window.showUseCase(useCase)
+ app.exec()
+
+
+if __name__ == "__main__":
+ main()