【问题标题】:Disable matplotlib widget in PyQt在 PyQt 中禁用 matplotlib 小部件
【发布时间】:2017-11-17 10:15:52
【问题描述】:

我有一个带有多个嵌入式 matplotlib 小部件 (https://github.com/chipmuenk/pyFDA) 的 pyQt 应用程序。

可以为每个绘图小部件关闭绘图的自动更新以加快应用程序的速度(尤其是 3D 绘图可能需要很长时间)。

不幸的是,我还没有完全禁用(灰色)画布。我想做的是做类似的事情

class MplWidget(QWidget):
    """
    Construct a subwidget with Matplotlib canvas and NavigationToolbar
    """

    def __init__(self, parent):
        super(MplWidget, self).__init__(parent)
        # Create the mpl figure and construct the canvas with the figure
        self.fig = Figure()
        self.pltCanv = FigureCanvas(self.fig)
#-------------------------------------------------

self.mplwidget = MplWidget(self)
self.mplwidget.pltCanv.setEnabled(False) # <- this doesn't work

以明确在此小部件中没有可交互的内容。有没有简单的解决方法?

【问题讨论】:

  • 这是关于将颜色更改为灰色还是关于阻止任何用户交互?
  • 阻止任何用户交互会更好,但“灰显”就足够了。但我什至没有设法做到这一点......
  • 变灰:使用与图一样大的补丁,将其zorder设置得很高,使其半透明。防止用户交互:断开所有事件与画布的连接(这是一个 matplotlib 操作,而不是 PyQt 之一)。 (我想我可以提供一个答案,但如果是第二个选项,则需要有一个 minimal reproducible example 可用于测试。)
  • 不,谢谢,使用补丁对我来说很好 - 另一个选项对于小的 UI 改进来说听起来太复杂了。作为第三种选择,我正在清除数字 (clf()) - 不太漂亮,但它也可以完成这项工作。如果您重新发布补丁解决方案作为答案,我可以给您一个信用。
  • 虽然我知道这个问题有一个不同的(视觉)上下文 - 因为它包含“禁用 matplotlib 小部件”:还有一个 matplotlib.widgets.Widget.set_active(active),它可能对应于禁用一个小部件。但请注意,Radio 和 CheckButtons 的 set_active 具有不同的含义!

标签: python matplotlib canvas pyqt figure


【解决方案1】:

灰色的图。

您可以通过在其顶部放置一个灰色的半透明补丁来使该图形变灰。为此,您可以创建一个 Rectangle,将其 zorder 设置得非常高,并对其进行图形变换。要将其添加到轴,您可以使用 ax.add_patch;但是,要将其添加到具有 3D 轴的图形中,这将不起作用,您需要通过 fig.patches.extend 添加它。 (见this answer

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot([1,3,2],[1,2,3],[2,3,2])

rect=plt.Rectangle((0,0),1,1, transform=fig.transFigure, 
                   clip_on=False, zorder=100, alpha=0.5, color="grey")
fig.patches.extend([rect])

plt.show()

断开所有事件

您可以断开所有事件与画布的连接。这将阻止任何用户交互,但也不可逆;因此,如果您在稍后阶段需要这些事件,则解决方案会更加复杂。

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot([1,3,2],[1,2,3],[2,3,2])

for evt, callback in fig.canvas.callbacks.callbacks.items():
    for cid, _ in callback.items():
        fig.canvas.mpl_disconnect(cid)
plt.show()

【讨论】:

  • 感谢您将答案扩展到 3D 轴(我确实需要)!
猜你喜欢
  • 1970-01-01
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 2013-05-08
  • 2012-08-27
  • 1970-01-01
  • 2011-06-17
相关资源
最近更新 更多