Вставить виджет Matplotlib в нескольких местах - PullRequest
4 голосов
/ 30 декабря 2011

У меня есть график matplotlib, который я хочу повторить в двух отдельных окнах под PyQt4. Я пытался добавить виджет в макет обоих, но затем виджет исчезает из первого. Есть ли способ сделать это, кроме создания двух одинаковых графиков и их синхронизации?

Ответы [ 2 ]

2 голосов
/ 16 декабря 2013

Проблема в том, что вы не можете добавить один и тот же виджет qt к двум разным родительским виджетам, потому что в процессе добавления виджета Qt также создает родительский процесс, который делает то, что вы видите:

... виджет исчезает из первого [окна] ...

Таким образом, решение состоит в том, чтобы сделать два холста с одинаковым рисунком. Вот пример кода, который покажет вам два основных окна, каждое из которых имеет два холста, и четыре графика будут синхронизированы:

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_())
0 голосов
/ 05 января 2012

Хотя это не идеальное решение, в matplotlib есть встроенный способ синхронизировать ограничения, тики и т. Д. Двух отдельных графиков.

Например,

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

Обратите внимание, чтовсе 3 графика будут синхронизированы при масштабировании, панорамировании и т. д.

Хотя, вероятно, есть лучший способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...