2011-12-30 4 views
4

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

ответ

0

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

E.g.

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 участка будут оставаться в синхронизации при увеличении, панорамирование и т.д.

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

2

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

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

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

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_()) 
Смежные вопросы