如何在 pyqt5 中使 matplotlib 绘图具有交互性
How to make a matplotlib plot interactive in pyqt5
背景
我目前正在做一个项目,我想将 matplotlib 绘图嵌入到 pyqt5 GUI 中。该图是交互式的,允许绘制阴影矩形。
问题
问题是当它被嵌入到 pyqt 中时,绘图是不可交互的 window。当我 运行 程序时,下面代码中的第 147 行(mplWidget class 中的 plt.show() )显示了 matplotlib 图,然后我可以绘制一个矩形,如您在此处看到的:
然而,当这个 window 关闭并且绘图嵌入到 pyqt 中时 window,它变得不可编辑
我希望 GUI 图能够像 matplotlib 图一样运行。
建议的解决方案/问题
我知道这与我必须使用 connect()
语句提供 pyqt 功能这一事实有关,但我不知道这些语句的去向/它们如何适合该程序。
我不知道如何连接到 matplotlib。我是否只对 mplWidget class 函数使用 connect()
语句?
任何帮助表示赞赏!
(我意识到我需要把第147行去掉(plt.show())这样图框就不会在gui之前弹出了,不过我只是暂时用它来显示mpl class 仍然按预期运行,问题是它在嵌入时变成“静态”)
代码
import numpy as np
import matplotlib.pyplot as plt
from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar)
class topLevelWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# Add a central widget to the main window and lay it out in a grid
self.centralwidget = QtWidgets.QWidget(self)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_5 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_5.setObjectName("gridLayout_5")
# Create mainTabs object as well as the displayFrame and displaySettingsFrame that go in the central widget
# Display Frame and Display settings frames
self.displayFrame = QtWidgets.QFrame(self.centralwidget)
self.verticalLayout_22 = QtWidgets.QVBoxLayout(self.displayFrame)
self.verticalLayout_22.setObjectName("verticalLayout_22")
self.gridLayout_5.addWidget(self.displayFrame, 1, 0, 1, 1)
self.devConstructor = mplWidget()
self.dynamic_canvas = FigureCanvasQTAgg(self.devConstructor.fig)
self.verticalLayout_22.addWidget(self.dynamic_canvas)
self._dynamic_ax = self.devConstructor.ax
self.setCentralWidget(self.centralwidget)
# Perform final windows setup (set buddies, translate, tab order, initial tabs, etc)
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("MainWindow", "MainWindow")) # Was self.setWindowTitle
QtCore.QMetaObject.connectSlotsByName(self)
self.show()
class mplWidget(QtWidgets.QWidget): # n.b. changed this from Object to QWidget and added a super()
def setSnapBase(self, base):
return lambda value: int(base*round(float(value)/base))
def onclick(self, event):
if self.plotSnap is False:
self.bottomLeftX = event.xdata
self.bottomLeftY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.bottomLeftX = self.calculateSnapCoordinates(event.xdata)
self.bottomLeftY = self.calculateSnapCoordinates(event.ydata)
try:
self.aspan.remove()
except:
pass
self.moving = True
def onrelease(self, event):
if self.plotSnap is False:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
try:
calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = calculateSnapCoordinates(event.xdata)
self.topRightY = calculateSnapCoordinates(event.ydata)
except:
pass
self.x = np.array([self.bottomLeftX, self.bottomLeftX, self.topRightX, self.topRightX, self.bottomLeftX])
self.y = np.array([self.bottomLeftY, self.topRightY, self.topRightY, self.bottomLeftY, self.bottomLeftY])
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
# ax.fill_between(x, y, color=defaultColors[0, :], alpha=.25)
ylimDiff = self.ax.get_ylim()[1] - self.ax.get_ylim()[0]
self.aspan = self.ax.axvspan(self.bottomLeftX, self.topRightX,
(self.bottomLeftY-self.ax.get_ylim()[0])/ylimDiff,
(self.topRightY-self.ax.get_ylim()[0])/ylimDiff,
color=self.defaultColors[0, :], alpha=.25)
self.moving = False
self.fig.canvas.draw()
def onmotion(self, event):
if self.moving is False:
return
if event.inaxes is None:
return
if event.button != 1:
return
if self.plotSnap is False:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = self.calculateSnapCoordinates(event.xdata)
self.topRightY = self.calculateSnapCoordinates(event.ydata)
self.x = np.array([self.bottomLeftX, self.bottomLeftX, self.topRightX, self.topRightX, self.bottomLeftX])
self.y = np.array([self.bottomLeftY, self.topRightY, self.topRightY, self.bottomLeftY, self.bottomLeftY])
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
self.fig.canvas.draw()
def __init__(self):
super(mplWidget, self).__init__()
# Set default colors array
self.defaultColors = np.array([[0, 0.4470, 0.7410], [0.8500, 0.3250, 0.0980], [0.9290, 0.6940, 0.1250],
[0.4660, 0.6740, 0.1880], [0.6350, 0.0780, 0.1840], [0.4940, 0.1840, 0.5560],
[0.3010, 0.7450, 0.9330]])
# Create a figure with axes
self.fig = plt.figure()
self.ax = self.fig.gca()
# Form the plot and shading
self.bottomLeftX = 0; self.bottomLeftY = 0; self.topRightX = 0; self.topRightY = 0
self.x = np.array([self.bottomLeftX, self.bottomLeftX, self.topRightX, self.topRightX, self.bottomLeftX])
self.y = np.array([self.bottomLeftY, self.topRightY, self.topRightY, self.bottomLeftY, self.bottomLeftY])
self.myPlot, = self.ax.plot(self.x, self.y, color=self.defaultColors[0, :])
self.aspan = self.ax.axvspan(self.bottomLeftX, self.topRightX, color= self.defaultColors[0, :], alpha=0)
# Set moving flag false (determines if mouse is being clicked and dragged inside plot). Set graph snap
self.moving = False
self.plotSnap = 5
# Set up connectivity
self.cid = self.fig.canvas.mpl_connect('button_press_event', self.onclick)
self.cid = self.fig.canvas.mpl_connect('button_release_event', self.onrelease)
self.cid = self.fig.canvas.mpl_connect('motion_notify_event', self.onmotion)
# Set plot limits and show it
plt.ylim((-100, 100))
plt.xlim((-100, 100))
plt.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = topLevelWindow()
sys.exit(app.exec_())
在你的代码中有很多,所以我只列出它们:
- 如果您打算使用 FigureCanvasQTAgg,那么您不应该再使用 pyplot。
- "mplWidget" 是一个 class,其唯一任务是重绘 canvas,所以它必须是 QWidget 吗?
- 如果您要比较布尔值,请不要使用“is”,例如
if self.plotSnap is False:
,只需 if not self.plotSnap:
我也认为认为“plotSnap”为 False 是不合逻辑的,如果您想要禁用然后设置一个不可能的值,例如 0 或负数。
考虑到上面我已经让 MplWidget 继承自 FigureCanvasQTAgg,我已经取消了 pyplot 的使用:
import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg,
NavigationToolbar2QT as NavigationToolbar,
)
from matplotlib.figure import Figure
class MplWidget(FigureCanvasQTAgg):
def __init__(self, parent=None):
fig = Figure()
super(MplWidget, self).__init__(fig)
self.setParent(parent)
# Set default colors array
self.defaultColors = np.array(
[
[0, 0.4470, 0.7410],
[0.8500, 0.3250, 0.0980],
[0.9290, 0.6940, 0.1250],
[0.4660, 0.6740, 0.1880],
[0.6350, 0.0780, 0.1840],
[0.4940, 0.1840, 0.5560],
[0.3010, 0.7450, 0.9330],
]
)
# Create a figure with axes
self.ax = self.figure.add_subplot(111)
# Form the plot and shading
self.bottomLeftX = 0
self.bottomLeftY = 0
self.topRightX = 0
self.topRightY = 0
self.x = np.array(
[
self.bottomLeftX,
self.bottomLeftX,
self.topRightX,
self.topRightX,
self.bottomLeftX,
]
)
self.y = np.array(
[
self.bottomLeftY,
self.topRightY,
self.topRightY,
self.bottomLeftY,
self.bottomLeftY,
]
)
(self.myPlot,) = self.ax.plot(self.x, self.y, color=self.defaultColors[0, :])
self.aspan = self.ax.axvspan(
self.bottomLeftX, self.topRightX, color=self.defaultColors[0, :], alpha=0
)
self.ax.set_xlim((-100, 100))
self.ax.set_ylim((-100, 100))
# Set moving flag false (determines if mouse is being clicked and dragged inside plot). Set graph snap
self.moving = False
self.plotSnap = 5
# Set up connectivity
self.cid1 = self.mpl_connect("button_press_event", self.onclick)
self.cid2 = self.mpl_connect("button_release_event", self.onrelease)
self.cid3 = self.mpl_connect("motion_notify_event", self.onmotion)
def setSnapBase(self, base):
return lambda value: int(base * round(float(value) / base))
def onclick(self, event):
if self.plotSnap <= 0:
self.bottomLeftX = event.xdata
self.bottomLeftY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.bottomLeftX = self.calculateSnapCoordinates(event.xdata)
self.bottomLeftY = self.calculateSnapCoordinates(event.ydata)
try:
self.aspan.remove()
except:
pass
self.moving = True
def onrelease(self, event):
if self.plotSnap <= 0:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
try:
calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = calculateSnapCoordinates(event.xdata)
self.topRightY = calculateSnapCoordinates(event.ydata)
except:
pass
self.x = np.array(
[
self.bottomLeftX,
self.bottomLeftX,
self.topRightX,
self.topRightX,
self.bottomLeftX,
]
)
self.y = np.array(
[
self.bottomLeftY,
self.topRightY,
self.topRightY,
self.bottomLeftY,
self.bottomLeftY,
]
)
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
# ax.fill_between(x, y, color=defaultColors[0, :], alpha=.25)
ylimDiff = self.ax.get_ylim()[1] - self.ax.get_ylim()[0]
self.aspan = self.ax.axvspan(
self.bottomLeftX,
self.topRightX,
(self.bottomLeftY - self.ax.get_ylim()[0]) / ylimDiff,
(self.topRightY - self.ax.get_ylim()[0]) / ylimDiff,
color=self.defaultColors[0, :],
alpha=0.25,
)
self.moving = False
self.draw()
def onmotion(self, event):
if not self.moving:
return
if event.inaxes is None:
return
if event.button != 1:
return
if self.plotSnap <= 0:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = self.calculateSnapCoordinates(event.xdata)
self.topRightY = self.calculateSnapCoordinates(event.ydata)
self.x = np.array(
[
self.bottomLeftX,
self.bottomLeftX,
self.topRightX,
self.topRightX,
self.bottomLeftX,
]
)
self.y = np.array(
[
self.bottomLeftY,
self.topRightY,
self.topRightY,
self.bottomLeftY,
self.bottomLeftY,
]
)
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
self.draw()
class TopLevelWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.canvas = MplWidget()
self.setCentralWidget(self.canvas)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = TopLevelWindow()
w.show()
sys.exit(app.exec_())
背景
我目前正在做一个项目,我想将 matplotlib 绘图嵌入到 pyqt5 GUI 中。该图是交互式的,允许绘制阴影矩形。
问题
问题是当它被嵌入到 pyqt 中时,绘图是不可交互的 window。当我 运行 程序时,下面代码中的第 147 行(mplWidget class 中的 plt.show() )显示了 matplotlib 图,然后我可以绘制一个矩形,如您在此处看到的:
然而,当这个 window 关闭并且绘图嵌入到 pyqt 中时 window,它变得不可编辑
我希望 GUI 图能够像 matplotlib 图一样运行。
建议的解决方案/问题
我知道这与我必须使用 connect()
语句提供 pyqt 功能这一事实有关,但我不知道这些语句的去向/它们如何适合该程序。
我不知道如何连接到 matplotlib。我是否只对 mplWidget class 函数使用 connect()
语句?
任何帮助表示赞赏!
(我意识到我需要把第147行去掉(plt.show())这样图框就不会在gui之前弹出了,不过我只是暂时用它来显示mpl class 仍然按预期运行,问题是它在嵌入时变成“静态”)
代码
import numpy as np
import matplotlib.pyplot as plt
from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar)
class topLevelWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# Add a central widget to the main window and lay it out in a grid
self.centralwidget = QtWidgets.QWidget(self)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_5 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_5.setObjectName("gridLayout_5")
# Create mainTabs object as well as the displayFrame and displaySettingsFrame that go in the central widget
# Display Frame and Display settings frames
self.displayFrame = QtWidgets.QFrame(self.centralwidget)
self.verticalLayout_22 = QtWidgets.QVBoxLayout(self.displayFrame)
self.verticalLayout_22.setObjectName("verticalLayout_22")
self.gridLayout_5.addWidget(self.displayFrame, 1, 0, 1, 1)
self.devConstructor = mplWidget()
self.dynamic_canvas = FigureCanvasQTAgg(self.devConstructor.fig)
self.verticalLayout_22.addWidget(self.dynamic_canvas)
self._dynamic_ax = self.devConstructor.ax
self.setCentralWidget(self.centralwidget)
# Perform final windows setup (set buddies, translate, tab order, initial tabs, etc)
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("MainWindow", "MainWindow")) # Was self.setWindowTitle
QtCore.QMetaObject.connectSlotsByName(self)
self.show()
class mplWidget(QtWidgets.QWidget): # n.b. changed this from Object to QWidget and added a super()
def setSnapBase(self, base):
return lambda value: int(base*round(float(value)/base))
def onclick(self, event):
if self.plotSnap is False:
self.bottomLeftX = event.xdata
self.bottomLeftY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.bottomLeftX = self.calculateSnapCoordinates(event.xdata)
self.bottomLeftY = self.calculateSnapCoordinates(event.ydata)
try:
self.aspan.remove()
except:
pass
self.moving = True
def onrelease(self, event):
if self.plotSnap is False:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
try:
calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = calculateSnapCoordinates(event.xdata)
self.topRightY = calculateSnapCoordinates(event.ydata)
except:
pass
self.x = np.array([self.bottomLeftX, self.bottomLeftX, self.topRightX, self.topRightX, self.bottomLeftX])
self.y = np.array([self.bottomLeftY, self.topRightY, self.topRightY, self.bottomLeftY, self.bottomLeftY])
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
# ax.fill_between(x, y, color=defaultColors[0, :], alpha=.25)
ylimDiff = self.ax.get_ylim()[1] - self.ax.get_ylim()[0]
self.aspan = self.ax.axvspan(self.bottomLeftX, self.topRightX,
(self.bottomLeftY-self.ax.get_ylim()[0])/ylimDiff,
(self.topRightY-self.ax.get_ylim()[0])/ylimDiff,
color=self.defaultColors[0, :], alpha=.25)
self.moving = False
self.fig.canvas.draw()
def onmotion(self, event):
if self.moving is False:
return
if event.inaxes is None:
return
if event.button != 1:
return
if self.plotSnap is False:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = self.calculateSnapCoordinates(event.xdata)
self.topRightY = self.calculateSnapCoordinates(event.ydata)
self.x = np.array([self.bottomLeftX, self.bottomLeftX, self.topRightX, self.topRightX, self.bottomLeftX])
self.y = np.array([self.bottomLeftY, self.topRightY, self.topRightY, self.bottomLeftY, self.bottomLeftY])
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
self.fig.canvas.draw()
def __init__(self):
super(mplWidget, self).__init__()
# Set default colors array
self.defaultColors = np.array([[0, 0.4470, 0.7410], [0.8500, 0.3250, 0.0980], [0.9290, 0.6940, 0.1250],
[0.4660, 0.6740, 0.1880], [0.6350, 0.0780, 0.1840], [0.4940, 0.1840, 0.5560],
[0.3010, 0.7450, 0.9330]])
# Create a figure with axes
self.fig = plt.figure()
self.ax = self.fig.gca()
# Form the plot and shading
self.bottomLeftX = 0; self.bottomLeftY = 0; self.topRightX = 0; self.topRightY = 0
self.x = np.array([self.bottomLeftX, self.bottomLeftX, self.topRightX, self.topRightX, self.bottomLeftX])
self.y = np.array([self.bottomLeftY, self.topRightY, self.topRightY, self.bottomLeftY, self.bottomLeftY])
self.myPlot, = self.ax.plot(self.x, self.y, color=self.defaultColors[0, :])
self.aspan = self.ax.axvspan(self.bottomLeftX, self.topRightX, color= self.defaultColors[0, :], alpha=0)
# Set moving flag false (determines if mouse is being clicked and dragged inside plot). Set graph snap
self.moving = False
self.plotSnap = 5
# Set up connectivity
self.cid = self.fig.canvas.mpl_connect('button_press_event', self.onclick)
self.cid = self.fig.canvas.mpl_connect('button_release_event', self.onrelease)
self.cid = self.fig.canvas.mpl_connect('motion_notify_event', self.onmotion)
# Set plot limits and show it
plt.ylim((-100, 100))
plt.xlim((-100, 100))
plt.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = topLevelWindow()
sys.exit(app.exec_())
在你的代码中有很多,所以我只列出它们:
- 如果您打算使用 FigureCanvasQTAgg,那么您不应该再使用 pyplot。
- "mplWidget" 是一个 class,其唯一任务是重绘 canvas,所以它必须是 QWidget 吗?
- 如果您要比较布尔值,请不要使用“is”,例如
if self.plotSnap is False:
,只需if not self.plotSnap:
我也认为认为“plotSnap”为 False 是不合逻辑的,如果您想要禁用然后设置一个不可能的值,例如 0 或负数。
考虑到上面我已经让 MplWidget 继承自 FigureCanvasQTAgg,我已经取消了 pyplot 的使用:
import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg,
NavigationToolbar2QT as NavigationToolbar,
)
from matplotlib.figure import Figure
class MplWidget(FigureCanvasQTAgg):
def __init__(self, parent=None):
fig = Figure()
super(MplWidget, self).__init__(fig)
self.setParent(parent)
# Set default colors array
self.defaultColors = np.array(
[
[0, 0.4470, 0.7410],
[0.8500, 0.3250, 0.0980],
[0.9290, 0.6940, 0.1250],
[0.4660, 0.6740, 0.1880],
[0.6350, 0.0780, 0.1840],
[0.4940, 0.1840, 0.5560],
[0.3010, 0.7450, 0.9330],
]
)
# Create a figure with axes
self.ax = self.figure.add_subplot(111)
# Form the plot and shading
self.bottomLeftX = 0
self.bottomLeftY = 0
self.topRightX = 0
self.topRightY = 0
self.x = np.array(
[
self.bottomLeftX,
self.bottomLeftX,
self.topRightX,
self.topRightX,
self.bottomLeftX,
]
)
self.y = np.array(
[
self.bottomLeftY,
self.topRightY,
self.topRightY,
self.bottomLeftY,
self.bottomLeftY,
]
)
(self.myPlot,) = self.ax.plot(self.x, self.y, color=self.defaultColors[0, :])
self.aspan = self.ax.axvspan(
self.bottomLeftX, self.topRightX, color=self.defaultColors[0, :], alpha=0
)
self.ax.set_xlim((-100, 100))
self.ax.set_ylim((-100, 100))
# Set moving flag false (determines if mouse is being clicked and dragged inside plot). Set graph snap
self.moving = False
self.plotSnap = 5
# Set up connectivity
self.cid1 = self.mpl_connect("button_press_event", self.onclick)
self.cid2 = self.mpl_connect("button_release_event", self.onrelease)
self.cid3 = self.mpl_connect("motion_notify_event", self.onmotion)
def setSnapBase(self, base):
return lambda value: int(base * round(float(value) / base))
def onclick(self, event):
if self.plotSnap <= 0:
self.bottomLeftX = event.xdata
self.bottomLeftY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.bottomLeftX = self.calculateSnapCoordinates(event.xdata)
self.bottomLeftY = self.calculateSnapCoordinates(event.ydata)
try:
self.aspan.remove()
except:
pass
self.moving = True
def onrelease(self, event):
if self.plotSnap <= 0:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
try:
calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = calculateSnapCoordinates(event.xdata)
self.topRightY = calculateSnapCoordinates(event.ydata)
except:
pass
self.x = np.array(
[
self.bottomLeftX,
self.bottomLeftX,
self.topRightX,
self.topRightX,
self.bottomLeftX,
]
)
self.y = np.array(
[
self.bottomLeftY,
self.topRightY,
self.topRightY,
self.bottomLeftY,
self.bottomLeftY,
]
)
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
# ax.fill_between(x, y, color=defaultColors[0, :], alpha=.25)
ylimDiff = self.ax.get_ylim()[1] - self.ax.get_ylim()[0]
self.aspan = self.ax.axvspan(
self.bottomLeftX,
self.topRightX,
(self.bottomLeftY - self.ax.get_ylim()[0]) / ylimDiff,
(self.topRightY - self.ax.get_ylim()[0]) / ylimDiff,
color=self.defaultColors[0, :],
alpha=0.25,
)
self.moving = False
self.draw()
def onmotion(self, event):
if not self.moving:
return
if event.inaxes is None:
return
if event.button != 1:
return
if self.plotSnap <= 0:
self.topRightX = event.xdata
self.topRightY = event.ydata
else:
self.calculateSnapCoordinates = self.setSnapBase(self.plotSnap)
self.topRightX = self.calculateSnapCoordinates(event.xdata)
self.topRightY = self.calculateSnapCoordinates(event.ydata)
self.x = np.array(
[
self.bottomLeftX,
self.bottomLeftX,
self.topRightX,
self.topRightX,
self.bottomLeftX,
]
)
self.y = np.array(
[
self.bottomLeftY,
self.topRightY,
self.topRightY,
self.bottomLeftY,
self.bottomLeftY,
]
)
self.myPlot.set_xdata(self.x)
self.myPlot.set_ydata(self.y)
self.draw()
class TopLevelWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.canvas = MplWidget()
self.setCentralWidget(self.canvas)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = TopLevelWindow()
w.show()
sys.exit(app.exec_())