Matplotlib 将图形嵌入到 UI PyQt5

Posted

技术标签:

【中文标题】Matplotlib 将图形嵌入到 UI PyQt5【英文标题】:Matplotlib Embed a graph in to a UI PyQt5 【发布时间】:2017-04-18 16:00:36 【问题描述】:

我在另一个脚本中有一个绘制图表的函数,所以该图表已经预先绘制,我只想将它放在我的 PyQt5 界面上的一个小部件中。我已经导入它,当它运行时会打开两个窗口,一个带有图形,一个带有用户界面。有什么想法吗?

代码如下:

def minionRatioGraph(recentMinionRatioAvg):
    x = recentMinionRatioAvg
    a = x*10
    b = 100-a
    sizes = [a, b]
    colors = ['#0047ab', 'lightcoral']
    plt.pie(sizes, colors=colors)

    #determine score colour as scolour
    if x < 5:
       scolour = "#ff6961" #red
    elif 5 <= x < 5.5:
       scolour = "#ffb347" #orange
    elif 5.5 <= x < 6.5:
       scolour = "#77dd77" #light green
    elif 6.5 <= x:
       scolour = "#03c03c" # dark green

    #draw a circle at the center of pie to make it look like a donut
    centre_circle = plt.Circle((0,0),0.75, fc=scolour,linewidth=1.25)
    fig = plt.gcf()
    fig.gca().add_artist(centre_circle)

    # Set aspect ratio to be equal so that pie is drawn as a circle.
    plt.axis('equal')
    plt.show()

这是一个脚本。在我的 GUI 脚本中,我已经导入了这些:

from PyQt5 import QtCore, QtGui, QtWidgets
import sqlite3
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as 
FigureCanvas
from graphSetup import *

在我的窗口类开始时,在设置功能之前,我有这个功能:

def minionGraphSetup(self, recentMinionRatioAvg):
    minionRatioGraph(recentMinionRatioAvg)

【问题讨论】:

【参考方案1】:

您需要将导入脚本生成的图形放入 PyQt GUI 的 FigureCanvas 中,而不是调用 plt.show

所以在你的绘图脚本中做

def minionRatioGraph(recentMinionRatioAvg):
    ...
    fig = plt.gcf()
    fig.gca().add_artist(centre_circle)
    plt.axis('equal')
    #plt.show() <- don't show window!
    return fig

在您的 GUI 脚本中,使用获得的图形将其放入画布中。

def minionGraphSetup(self, recentMinionRatioAvg):
    fig = minionRatioGraph(recentMinionRatioAvg)
    ...
    self.canvas = FigureCanvas(fig, ...)


如果要返回图像,可以将其保存到 Byte 缓冲区,
import io
def minionRatioGraph(recentMinionRatioAvg):
    ...
    fig = plt.gcf()
    fig.gca().add_artist(centre_circle)
    plt.axis('equal')
    buff = io.BytesIO()
    plt.savefig(buff, format="png")
    return buff

然后在 PyQt GUI 中将其显示为图像。 (我还没有测试过下面的,所以它可能会有点不同。)

def minionGraphSetup(self, recentMinionRatioAvg):
    image = minionRatioGraph(recentMinionRatioAvg)
    label = QLabel() 
    pixmap = QPixmap(image)
    label.setPixmap(pixmap)

【讨论】:

虽然这行得通,但这不是我想要的,不是你的错,我的。你知道我怎么可能将图形作为图像直接导出到 gui 吗?我知道您可以将图形保存为图像,但是据我所知,如何将更新后的图像放在屏幕上,当您编译资源文件时,所有图像都保持不变,我不知道如何重新加载它。 我更新了一张图片的答案。我目前无法对其进行测试,因此请将其作为路线图而不是工作代码。 代码在pixmap = QPixmap(image) 停止工作,我不确定为什么?有什么想法吗?另外,我怎么把它放在我的窗户上?我会传入窗口的名称并将 self.centralwidget 放入 QLabel 括号中吗?谢谢

以上是关于Matplotlib 将图形嵌入到 UI PyQt5的主要内容,如果未能解决你的问题,请参考以下文章

在 PyQt5 中嵌入 Matplotlib 图形

当我在 PyQt5 窗口中嵌入 Matplotlib 图形时,为啥有两个重复的轴标签?

在 pyqt5 小部件中更新 matplotlib

在 PyQt5 中嵌入 Matplotlib:工具栏不起作用

在 PyQt4 的嵌入式 matplotlib 图中使用 ginput

Matplotlib植入PyQt5 + QT5的UI呈现