from __future__ import annotations
#-----------------------------------------------------------------------------
# Company : SLAC National Accelerator Laboratory
#-----------------------------------------------------------------------------
# Description:
# PyRogue PyDM Plot Window
#-----------------------------------------------------------------------------
# This file is part of the rogue software platform. It is subject to
# the license terms in the LICENSE.txt file found in the top-level directory
# of this distribution and at:
# https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
# No part of the rogue software platform, including this file, may be
# copied, modified, propagated, or distributed except according to the terms
# contained in the LICENSE.txt file.
#-----------------------------------------------------------------------------
from pydm.widgets.frame import PyDMFrame
from pyrogue.pydm.data_plugins.rogue_plugin import nodeFromAddress
from qtpy.QtWidgets import QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
[docs]
class Plotter(PyDMFrame):
"""PyDM widget that displays an incoming matplotlib figure published by a pyrogue Variable.
Parameters
----------
parent : QWidget | None, optional
Parent Qt widget.
init_channel : str | None, optional
Initial Rogue channel address.
"""
def __init__(self, parent: QWidget | None = None, init_channel: str | None = None) -> None:
PyDMFrame.__init__(self, parent, init_channel)
self._systemLog = None
self._node = None
self._canvas = None
self._fig = None
[docs]
def connection_changed(self, connected: bool) -> None:
"""Build the layout after the first successful channel connection."""
build = (self._node is None) and (self._connected != connected and connected is True)
super(Plotter, self).connection_changed(connected)
if not build:
return
self._node = nodeFromAddress(self.channel)
self._vb = QVBoxLayout()
self.setLayout(self._vb)
[docs]
def value_changed(self, new_val: object) -> None:
"""Replace the displayed plot with the latest figure object."""
if self._canvas is not None:
self._vb.removeWidget(self._canvas)
self._vb.removeWidget(self._nav)
self._canvas.setParent(None)
self._nav.setParent(None)
del self._canvas, self._nav, self._fig
self._fig = new_val
self._canvas = FigureCanvas(self._fig)
self._nav = NavigationToolbar(self._canvas, self)
self._vb.addWidget(self._nav)
self._vb.addWidget(self._canvas)