- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 PyQt4 和 matplotlib 创建一个实时数据监视器 GUI 来创建绘图。 GUI 一次显示多个绘图(大约 6 或 7 个)。为了给 GUI 线程更多的时间和稍微更好的响应时间,我只执行绘图 canvas.draw()
和我在更新绘图数据的线程中执行的所有其他绘图命令。因此,在非 GUI 线程中,我执行诸如 line.set_ydata
、ax.set_ylim
和其他可能需要更新的命令。
两个线程可以通过在初始化时传递给两个线程的字典访问图形和 Canvas 对象。当非 GUI 线程获取数据并更新绘图时,它会通知 GUI 线程使用 Qts 信号(自动连接)重绘 Canvas 。我的线程经验告诉我,我应该使用锁或确保非 GUI 线程以某种方式在重绘时被阻塞,但在我的编码匆忙中,我从来没有把它放进去,直到现在才忘记它。这种情况的关键是我想看到情节的每次更新,而不是在其他线程更新的中间重绘,甚至错过更新(如果这有意义的话)。目前,我认为我只是幸运地把握了时机,事情似乎进展顺利。
另一件可能有帮助的事情是,我通过使用 moveToThread 将 QObject 移动到 QThread 来创建线程。
我的问题是:
我可能应该注意到,这是我第一次尝试使 GUI 响应更快(将 matplotlib 命令移到数据线程中),我可能会转向 blit 动画风格的绘图,只更新绘图中发生变化的部分。但我仍然很好奇我到底有多幸运。
感谢您的帮助。
更新/澄清/评论的延续:我希望整个监控系统能够由可能只熟悉 matlab 和 matplotlib 的科学家轻松更改/更新。我并不完全反对改用 pyqwt 来提高速度。就每秒帧数而言,我根本不需要太多,因为标称的每 0.5 秒(最快 0.2 秒)才绘制一次数据。 GUI 响应能力似乎“吃掉了**”,因为有太多的情节。我已经用 matplotlib blitting 对我的代码进行了概念验证,它似乎有很大帮助,如果需要,pyqwt 将会发生。我之前的问题仍然有效。
最佳答案
我偶然发现了类似的问题。我有很多图要画 (~250),所以我的 GUI 窗口最终会显示为卡在 Windows 中。我修改了图形类以作为单独的线程执行绘图。结果 - 我的 GUI 不再挂起,绘图窗口在绘图完成后显示。要使用它,您需要创建 PlotDialog
实例并使用 plot_data
参数调用 draw_plots
方法。 plot_data
是一个字典列表,每个字典代表子图。每个子图都有以下键(和相应的数据):title
、xlabel
、ylabel
和data
。希望这是有道理的。
这是我的代码:
import math
from PyQt4 import QtCore, QtGui
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
class MyFigure(Figure, QtCore.QThread):
def __init__(self, parent, *args, **kwargs):
QtCore.QThread.__init__(self, parent)
Figure.__init__(self, *args, **kwargs)
self.plot_data = list()
def start_plotting_thread(self, plot_data, on_finish=None):
""" Start plotting """
self.plot_data = plot_data
if on_finish is not None:
self.finished.connect(on_finish)
self.start()
def run(self):
""" Run as a thread """
# Figure out rows and columns
total_plots = len(self.plot_data)
columns = int(math.sqrt(total_plots))
if columns < 1:
columns = 1
rows = int(total_plots / columns)
if (total_plots % columns) > 0:
rows += 1
if rows < 1:
rows = 1
# Plot Data
for plot_index, _plot_data in enumerate(self.plot_data):
plot_number = plot_index + 1
args = (rows, columns, plot_number)
kwargs = {
'title': _plot_data['title'],
'xlabel': _plot_data['xlabel'],
'ylabel': _plot_data['ylabel']
}
figure = self.add_subplot(*args, **kwargs)
figure.plot(_plot_data['data'])
class PlotDialog(QtGui.QDialog):
def __init__(self, parent):
super(PlotDialog, self).__init__(parent, QtCore.Qt.WindowMinMaxButtonsHint | QtCore.Qt.WindowCloseButtonHint)
self.figure = MyFigure(self)
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
self.layout = QtGui.QGridLayout()
self.setLayout(self.layout)
layout = [
[self.canvas],
[self.toolbar],
]
for row_index, columns in enumerate(layout):
if type(columns) is list:
for column_index, widget in enumerate(columns):
if widget is not None:
self.layout.addWidget(widget, row_index, column_index)
def draw_plots(self, plot_data):
""" Plot Plots """
self.figure.start_plotting_thread(plot_data, on_finish=self.finish_drawing_plots)
def finish_drawing_plots(self):
""" Finish drawing plots """
self.canvas.draw()
self.show()
关于python - matplotlib 和 pyqt4 : update plot in one thread, 画在另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7294145/
我想以 headless 模式(屏幕上根本没有 GUI)将 JPanel 绘制到 BufferedImage 中。 final JPanel panel = createPanel(); panel.
我是 Canvas 的新手,正在尝试创建看起来逼真的 float 粒子动画。 目前,我正在创建 400 个随机散布在 400x400 Canvas 上的粒子。 然后,在每个 requestAnimat
有没有办法在悬停时停止悬 float 画? :hover 这是一个显示动画的链接: https://codepen.io/youbiteme/pen/RprPrN 最佳答案 只需为您的 svg 悬停添
我想在谷歌地图上绘制覆盖图,其中除了特定点周围 1.5 公里半径以外的所有内容都被遮蔽了。为此,我尝试使用带有大量边框的圆圈,所以我会在边框中放置透明中心和覆盖颜色来实现这一点,但它无法渲染。
我正在尝试通过扩展类 UIView 来创建自定义 View ,该类可以在自定义 View 的中心显示一个圆圈。为了添加自定义绘图,我重写了 draw(_ rect: CGRect) 方法,如下所示。
我是一名优秀的程序员,十分优秀!