Insert matplotlib widget in multiple places

I have a matplotlib graph that I want to repeat in two separate windows, under PyQt4. I tried to add the widget to the layout of both, but then the widget will disappear from the first. Is there any way to do this, besides creating two identical graphs and synchronizing them?

+4
source share
2 answers

The problem is that you cannot add the same Qt widget to two different parent widgets, because when you add a Qt widget, also create a repeating process that does what you see:

... the widget disappears from the first [window] ...

So the solution is to make two canvases that have the same pattern. Here is a sample code, this will show you two main windows, each of which has two canvases, and four graphs will be synchronized:

import sys from PyQt4 import QtGui import numpy as np import numpy.random as rd from matplotlib.figure import Figure from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas class ApplicationWindow(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) self.main_widget = QtGui.QWidget(self) vbl = QtGui.QVBoxLayout(self.main_widget) self._fig = Figure() self.ax = self._fig.add_subplot(111) #note the same fig for two canvas self.fc1 = FigureCanvas(self._fig) #canvas #1 self.fc2 = FigureCanvas(self._fig) #canvas #1 self.but = QtGui.QPushButton(self.main_widget) self.but.setText("Update") #for testing the sync vbl.addWidget(self.fc1) vbl.addWidget(self.fc2) vbl.addWidget(self.but) self.setCentralWidget(self.main_widget) @property def fig(self): return self._fig @fig.setter def fig(self, value): self._fig = value #keep the same fig in both canvas self.fc1.figure = value self.fc2.figure = value def redraw_plot(self): self.fc1.draw() self.fc2.draw() qApp = QtGui.QApplication(sys.argv) aw1 = ApplicationWindow() #window #1 aw2 = ApplicationWindow() #window #2 aw1.fig = aw2.fig #THE SAME FIG FOR THE TWO WINDOWS! def update_plot(): '''Just a random plot for test the sync!''' #note that the update is only in the first window ax = aw1.fig.gca() ax.clear() ax.plot(range(10),rd.random(10)) #calls to redraw the canvas aw1.redraw_plot() aw2.redraw_plot() #just for testing the update aw1.but.clicked.connect(update_plot) aw2.but.clicked.connect(update_plot) aw1.show() aw2.show() sys.exit(qApp.exec_()) 
+2
source

Although this is not an ideal solution, matplotlib has a built-in way to save restrictions, ticks, etc. two separate graphs in sync.

eg.

 import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 4 * np.pi, 100) y = np.cos(x) figures = [plt.figure() for _ in range(3)] ax1 = figures[0].add_subplot(111) axes = [ax1] + [fig.add_subplot(111, sharex=ax1, sharey=ax1) for fig in figures[1:]] for ax in axes: ax.plot(x, y, 'go-') ax1.set_xlabel('test') plt.show() 

Please note that all 3 graphs will remain in sync when zooming, panning, etc.

Probably the best way to do this.

0
source

Source: https://habr.com/ru/post/1388557/


All Articles