#python #matplotlib #draw
#python #matplotlib #рисовать
Вопрос:
Я пытаюсь обновить график matplotlib, встроенный в окно pyqt5. Я использовал self.canvas.draw()
(в update
функции) для обновления графика в функции для перерисовки фигуры. Это отлично работает в Window, но не работает в macOS. Я не понимаю, почему и существует ли решение для этого?
На самом деле мне нужно щелкнуть по осям, чтобы рисунок был обновлен… странно.
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import numpy as np
import sys
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
class StimEdit(QMainWindow):
def __init__(self, parent=None):
super(StimEdit, self).__init__()
self.parent = parent
self.centralWidget = QWidget()
self.color = self.centralWidget.palette().color(QPalette.Background)
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QHBoxLayout()
self.set_Stims()
self.mainHBOX_param_scene.addWidget(self.Stimulation)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
def set_Stims(self):
self.Stimulation = QGroupBox('Stim N°1')
self.layout_Stimulation_courbe = QVBoxLayout()
self.layout_Stimulation = QHBoxLayout()
self.button = QPushButton('push')
self.masceneparam = paramViewer(self)
self.button.clicked.connect(self.button_fun)
self.layout_Stimulation_courbe.addWidget(self.masceneparam)
self.layout_Stimulation_courbe.addWidget(self.button)
self.Stimulation.setLayout(self.layout_Stimulation_courbe)
def button_fun(self):
self.masceneparam.update()
self.parent.processEvents()
class paramViewer(QGraphicsView):
def __init__(self, parent=None):
super(paramViewer, self).__init__(parent)
self.parent=parent
self.scene = QGraphicsScene(self)
self.setScene(self.scene)
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
self.axes_stim=self.figure.add_subplot(111)
self.canvas.setGeometry(0, 0, 1600, 500 )
layout = QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.setLayout(layout)
self.canvas.show()
def update(self):
self.axes_stim.clear()
t = np.arange(1000)/100
self.axes_stim.plot(t,np.sin(2*np.pi*np.random.uniform()*100*t))
self.canvas.draw()
def main():
app = QApplication(sys.argv)
ex = StimEdit(app)
ex.setWindowTitle('St ')
ex.show()
sys.exit(app.exec_( ))
if __name__ == '__main__':
main()
Редактировать
Я пытаюсь использовать пример matplotlib для встроенных фигур в Qt (https://matplotlib.org/gallery/user_interfaces/embedding_in_qt_sgskip.html ) от @ImportanceOfBeingErnest
# from PyQt5.QtGui import *
# from PyQt5.QtWidgets import *
import numpy as np
import sys
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
from matplotlib.backends.backend_qt4agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class StimEdit(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(StimEdit, self).__init__()
self.parent = parent
self.centralWidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QtWidgets.QHBoxLayout()
self.set_Stims()
self.mainHBOX_param_scene.addWidget(self.Stimulation)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
def set_Stims(self):
self.Stimulation = QtWidgets.QGroupBox('Stim N°1')
self.layout_Stimulation_courbe = QtWidgets.QVBoxLayout()
self.layout_Stimulation = QtWidgets.QHBoxLayout()
self.button = QtWidgets.QPushButton('push')
self.masceneparam = paramViewer(self)
self.button.clicked.connect(self.button_fun)
self.layout_Stimulation_courbe.addWidget(self.masceneparam)
self.layout_Stimulation_courbe.addWidget(self.button)
self.Stimulation.setLayout(self.layout_Stimulation_courbe)
def button_fun(self):
self.masceneparam.update()
self.parent.processEvents()
class paramViewer(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(paramViewer, self).__init__(parent)
self.parent=parent
self.scene = QtWidgets.QGraphicsScene(self)
self.setScene(self.scene)
self.figure = Figure()
self.canvas = FigureCanvas(self.figure )
self.toolbar = NavigationToolbar(self.canvas, self)
self.axes_stim=self.figure.add_subplot(111)
self.canvas.setGeometry(0, 0, 1600, 500 )
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.setLayout(layout)
self.canvas.show()
def update(self):
self.axes_stim.clear()
t = np.arange(1000)/100
self.axes_stim.plot(t,np.sin(2*np.pi*np.random.uniform()*100*t))
self.canvas.figure.canvas.draw()
# self.canvas.draw()
def main():
app = QtWidgets.QApplication(sys.argv)
ex = StimEdit(app)
ex.setWindowTitle('St ')
ex.show()
sys.exit(app.exec_( ))
if __name__ == '__main__':
main()
Но проблема все еще остается.
Комментарии:
1. Обратите внимание, что, как правило, не рекомендуется встраивать рисунки pyplot в пользовательские графические интерфейсы. Итак, я бы начал с того, что избавился от pyplot здесь. Проверьте пример в документации matplotlib.
2. Я попытался использовать импорт рисунка из matplotlib.figure вместо pyplot, но проблема остается той же. Я отредактировал сообщение.
3. Поскольку у меня нет никакого опыта работы с Mac, я, возможно, не смогу здесь больше помочь, но последним предложением может быть замена
.draw()
наdraw_idle()
. (Оба должны работать в этом случае, но вы никогда не знаете …)4. Я поражен. Парень, не имеющий опыта работы с Mac, найдет решение :). Это здорово
Ответ №1:
Ответ от @ImportanceOfBeingErnest
Поскольку у меня нет никакого опыта работы с Mac, я, возможно, не смогу здесь больше помочь, но последним предложением может быть замена .draw()
на .draw_idle()
. (Оба должны работать в этом случае, но вы никогда не знаете …)
Комментарии:
1. Использование
draw_idle()
вместоdraw()
сработало для меня в macOS. Не могли бы вы вкратце рассказать о разнице между ними?