Skip to content

Commit

Permalink
Merge branch 'main' into use-mpl-font-for-opengl
Browse files Browse the repository at this point in the history
  • Loading branch information
t20100 authored Dec 21, 2023
2 parents 3d76062 + 6a86f24 commit 18c85d6
Show file tree
Hide file tree
Showing 12 changed files with 594 additions and 149 deletions.
375 changes: 375 additions & 0 deletions examples/compareBackends.py
Original file line number Diff line number Diff line change
@@ -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.
#
# ###########################################################################*/

"""
Compare one to one backend rendering
"""

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

0 comments on commit 18c85d6

Please sign in to comment.