Minimal example for a GUI, where draw()
should only be called once per plot refresh. Keeps the correct scale factor. Can also be used with locked exponent, e.g. like here.
As an example I've just added a simple button to refresh the plot, but it could just as well be any other event.
from PyQt5.Qt import *
from PyQt5 import QtWidgets, QtCore # sorry about the Qt Creator mess
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.ticker import ScalarFormatter
import numpy as np
class WidgetPlot(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setLayout(QVBoxLayout())
self.canvas = PlotCanvas(self)
self.layout().addWidget(self.canvas)
class PlotCanvas(FigureCanvas):
def __init__(self, parent = None, width = 5, height = 5, dpi = 100):
self.fig = Figure(figsize = (width, height), dpi = dpi, tight_layout = True)
self.ax = self.fig.add_subplot(111)
FigureCanvas.__init__(self, self.fig)
def majorFormatterInLabel(self, ax, axis, axis_label, major_formatter):
if axis == "x":
axis = ax.xaxis
if axis == "y":
axis = ax.yaxis
axis.set_major_formatter(major_formatter)
axis.offsetText.set_visible(False)
exponent = axis.get_offset_text().get_text()
axis.set_label_text(axis_label + " (" + exponent + ")")
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(674, 371)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.gridLayoutWidget.setGeometry(QtCore.QRect(50, 10, 601, 281))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.mpl_layoutBox = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.mpl_layoutBox.setContentsMargins(0, 0, 0, 0)
self.mpl_layoutBox.setObjectName("mpl_layoutBox")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(280, 300, 113, 32))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.w = WidgetPlot()
self.canvas = self.w.canvas
self.mpl_layoutBox.addWidget(self.w)
self.pushButton.clicked.connect(self.refresh)
def refresh(self):
self.canvas.ax.clear()
# Could've made it more beautiful. In any case, the cost of doing this is sub-ms.
formatter = ScalarFormatter()
formatter.set_powerlimits((-1, 1))
self.canvas.majorFormatterInLabel(self.canvas.ax, "y", "label", major_formatter = formatter)
r = np.random.choice((1e3, 1e5, 1e7, 1e9, 1e100))
self.canvas.ax.plot(r)
self.canvas.draw()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
TraceWindow = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(TraceWindow)
TraceWindow.show()
sys.exit(app.exec_())