在 PyQt 中嵌入“图形类型”Seaborn 图(pyqtgraph)

2023-12-04

我正在使用 PyQt 的包装器(pyqtgraph) 构建 GUI 应用程序。 我希望嵌入一个Seaborn使用其中的绘图MatplotlibWidget。但是,我的问题是 Seaborn 包装方法,例如FacetGrid不接受外部图形句柄。此外,当我尝试更新 MatplotlibWidget 对象底层图时(.fig)与产生的数字FacetGrid它不起作用(之后没有情节draw)。有什么解决方法的建议吗?


西伯恩的Facetgrid提供了一个方便的功能来快速将 pandas 数据帧连接到 matplotlib pyplot 接口。

然而,在 GUI 应用程序中,您很少想使用 pyplot,而是使用 matplotlib API。

你在这里面临的问题是Facetgrid已经创建了自己的matplotlib.figure.Figure目的 (Facetgrid.fig)。另外,MatplotlibWidget 创建自己的图形,因此最终会得到两个图形。

现在,让我们退一步: 原则上可以使用seabornFacetgrid在 PyQt 中绘图,首先创建绘图,然后将生成的图形提供给图形画布(matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg)。以下是如何执行此操作的示例。

from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import sys
import seaborn as sns
import matplotlib.pyplot as plt

tips = sns.load_dataset("tips")


def seabornplot():
    g = sns.FacetGrid(tips, col="sex", hue="time", palette="Set1",
                                hue_order=["Dinner", "Lunch"])
    g.map(plt.scatter, "total_bill", "tip", edgecolor="w")
    return g.fig


class MainWindow(QtGui.QMainWindow):
    send_fig = QtCore.pyqtSignal(str)

    def __init__(self):
        super(MainWindow, self).__init__()

        self.main_widget = QtGui.QWidget(self)

        self.fig = seabornplot()
        self.canvas = FigureCanvas(self.fig)

        self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
                      QtGui.QSizePolicy.Expanding)
        self.canvas.updateGeometry()
        self.button = QtGui.QPushButton("Button")
        self.label = QtGui.QLabel("A plot:")

        self.layout = QtGui.QGridLayout(self.main_widget)
        self.layout.addWidget(self.button)
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.canvas)

        self.setCentralWidget(self.main_widget)
        self.show()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    sys.exit(app.exec_())

虽然这工作得很好,但它是否有用还是有点值得怀疑的。在大多数情况下,在 GUI 内创建绘图的目的是根据用户交互进行更新。在上面的示例中,这是非常低效的,因为它需要创建一个新的图形实例,使用该图形创建一个新的画布,并用新的画布实例替换旧的画布实例,将其添加到布局中。

请注意,这个问题特定于seaborn中的那些绘图函数,它们在图形级别上工作,例如lmplot, factorplot, jointplot, FacetGrid可能还有其他。
其他功能如regplot, boxplot, kdeplot在轴级别上工作并接受 matplotlibaxes对象作为参数(sns.regplot(x, y, ax=ax1)).


A 可能的解决方案是首先创建子图轴,然后绘制到这些轴,例如使用pandas 绘图功能.

df.plot(kind="scatter", x=..., y=..., ax=...)

where ax应设置为先前创建的轴。
这允许更新 GUI 内的绘图。请参阅下面的示例。当然正常的 matplotlib 绘图(ax.plot(x,y))或使用上面讨论的 seaborn 轴水平函数同样有效。

from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import sys
import seaborn as sns

tips = sns.load_dataset("tips")

class MainWindow(QtGui.QMainWindow):
    send_fig = QtCore.pyqtSignal(str)

    def __init__(self):
        super(MainWindow, self).__init__()

        self.main_widget = QtGui.QWidget(self)

        self.fig = Figure()
        self.ax1 = self.fig.add_subplot(121)
        self.ax2 = self.fig.add_subplot(122, sharex=self.ax1, sharey=self.ax1)
        self.axes=[self.ax1, self.ax2]
        self.canvas = FigureCanvas(self.fig)

        self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding, 
                                  QtGui.QSizePolicy.Expanding)
        self.canvas.updateGeometry()

        self.dropdown1 = QtGui.QComboBox()
        self.dropdown1.addItems(["sex", "time", "smoker"])
        self.dropdown2 = QtGui.QComboBox()
        self.dropdown2.addItems(["sex", "time", "smoker", "day"])
        self.dropdown2.setCurrentIndex(2)

        self.dropdown1.currentIndexChanged.connect(self.update)
        self.dropdown2.currentIndexChanged.connect(self.update)
        self.label = QtGui.QLabel("A plot:")

        self.layout = QtGui.QGridLayout(self.main_widget)
        self.layout.addWidget(QtGui.QLabel("Select category for subplots"))
        self.layout.addWidget(self.dropdown1)
        self.layout.addWidget(QtGui.QLabel("Select category for markers"))
        self.layout.addWidget(self.dropdown2)

        self.layout.addWidget(self.canvas)

        self.setCentralWidget(self.main_widget)
        self.show()
        self.update()

    def update(self):

        colors=["b", "r", "g", "y", "k", "c"]
        self.ax1.clear()
        self.ax2.clear()
        cat1 = self.dropdown1.currentText()
        cat2 = self.dropdown2.currentText()
        print cat1, cat2

        for i, value in enumerate(tips[cat1].unique().get_values()):
            print "value ", value
            df = tips.loc[tips[cat1] == value]
            self.axes[i].set_title(cat1 + ": " + value)
            for j, value2 in enumerate(df[cat2].unique().get_values()):
                print "value2 ", value2
                df.loc[ tips[cat2] == value2 ].plot(kind="scatter", x="total_bill", y="tip", 
                                                ax=self.axes[i], c=colors[j], label=value2)
        self.axes[i].legend()   
        self.fig.canvas.draw_idle()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    sys.exit(app.exec_())

enter image description here


A final word about pyqtgraph: I wouldn't call pyqtgraph a wrapper for PyQt but more an extention. Although pyqtgraph ships with its own Qt (which makes it portable and work out of the box), it is also a package one can use from within PyQt. You can therefore add a GraphicsLayoutWidget to a PyQt layout simply by
self.pgcanvas = pg.GraphicsLayoutWidget()
self.layout().addWidget(self.pgcanvas) 

这同样适用于MatplotlibWidget (mw = pg.MatplotlibWidget())。虽然您可以使用这种小部件,但它只是一个方便的包装器,因为它所做的只是找到正确的 matplotlib 导入并创建一个Figure and a FigureCanvas实例。除非您使用其他 pyqtgraph 功能,否则仅为了节省 5 行代码而导入完整的 pyqtgraph 包对我来说似乎有点过大了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PyQt 中嵌入“图形类型”Seaborn 图(pyqtgraph) 的相关文章

  • 是否可以更新动画中的箭袋位置坐标?

    我想用 matplotlib 绘制一些粒子并为其设置动画 每个点都有一个位置和速度 我可以使用 matplotlib 绘制单帧quiver 但是如何更新每一帧的箭袋数据呢 我正在使用 matplotlib 动画类 我读到了有关 未记录 qu
  • 在 matplotlib 中绘制多边形的并集[重复]

    这个问题在这里已经有答案了 我正在尝试绘制几个多边形的并集matplotlib 具有一定的 alpha 水平 我当前的代码在交叉点处颜色较深 有没有办法让交叉路口与其他地方的颜色相同 import matplotlib pyplot as
  • 如何调整 matplotlib 单选按钮的大小和纵横比?

    我已经尝试了几个小时来使简单的单选按钮列表的大小和纵横比正确 但没有成功 首先 导入模块 import matplotlib pyplot as plt from matplotlib widgets import RadioButtons
  • 使用seaborn绘制简单线图

    我正在尝试使用seaborn python 绘制ROC曲线 对于 matplotlib 我只需使用该函数plot plt plot one minus specificity sensitivity bs where one minus s
  • Matplotlib loglog 的错误刻度/标签(双轴)

    我正在使用 matplotlib 创建对数图 如下图所示 默认刻度选择得很糟糕 充其量是这样 右边的 y 轴甚至根本没有 在线性等效中确实如此 而两个 x 轴都只有一个 有没有办法获得合理数量的带有标签的刻度 without为每个情节手动指
  • 如何在 Seaborn 中叠加两个图表?

    如何在 Seaborn 中叠加两个图表 我的数据中有两列 我希望将它们放在同一个图表中 我怎样才能保留两个图的标签 对单个轴进行操作的seaborn 函数可以将一个轴作为参数 例如 文档seaborn kdeplot http web st
  • 如何更改 FacetGrid 中的边距标题颜色

    使用 Seaborn Facet Grids 如何仅更改边距标题的颜色 注意g set titles color red 更改两个标题 p sns load dataset penguins sns displot data p x fli
  • Pandas 堆积条形图中元素的排序

    我正在尝试绘制有关某个地区 5 个地区的家庭在特定行业赚取的收入比例的信息 我使用 groupby 按地区对数据框中的信息进行排序 df df orig groupby District Portion of income value co
  • Matplotlib 与多处理冻结计算机

    我对 matplotlib 和多重处理有疑问 我启动第一个进程 在其中显示图像并选择一个区域 然后关闭图形 然后我启动另一个进程 在其中调用定期更新的图形函数 至此 一切正常 然后 当我尝试使用相同的图形功能启动另一个进程时 它冻结了我的整
  • matplotlibplot_surface命令的颜色条

    我修改了mplot3d示例代码 http matplotlib sourceforge net examples mplot3d surface3d demo2 html在保罗的帮助下完成我的申请 代码如下 from mpl toolkit
  • Matplotlib - 可以用寄生轴制作子图吗?

    我正在尝试制作一个包含两个子图的图表 每个子图都有一个寄生轴 如文档中所示here https matplotlib org examples axes grid demo parasite axes2 html 然而 虽然我可以用单个图复
  • 立体太阳图 matplotlib 极坐标图 python

    我正在尝试创建一个与以下类似的简单的立体太阳路径图 http wiki naturalfrequent com wiki Sun Path Diagram http wiki naturalfrequency com wiki Sun Pa
  • import matplotlib.pyplot 给出 AttributeError: 'NoneType' 对象没有属性 'is_interactive'

    我尝试在 Pycharm 控制台中导入 matplotlib pyplt import matplotlib pyplot as plt 然后作为回报我得到 Traceback most recent call last File D Pr
  • 来自 pandas 数据帧的烛台图,用日期替换索引

    此代码给出了带有移动平均线的烛台图 但 x 轴位于索引中 我需要 x 轴位于日期中 需要做什么改变 import numpy as np import pandas as pd import matplotlib pyplot as plt
  • Matplotlib 图例,跨列添加项目而不是向下添加项目

    对于下面的简单绘图 有没有办法让 matplotlib 填充图例 以便它从左到右填充行 而不是第一列然后第二列 gt gt gt from pylab import gt gt gt x arange 2 pi 2 pi 0 1 gt gt
  • 如何获取分类数据的分组条形图

    I have a big dataset with information about students And I have to build a graph of dependencies between different value
  • 如何在matplotlib中调整x轴

    I have a graph like this x轴上的数据表示小时 所以我希望x轴设置为0 24 48 72 而不是现在的值 很难看到 0 100 之间的数据 fig1 plt figure ax fig1 add subplot 11
  • 如何设置 plt.colorbar 中的刻度数?

    当我用颜色条绘制矩阵时 颜色条有 10 个刻度 由于颜色条必须非常小 因此刻度标签会重叠 因此我想将刻度数从 10 减少到 5 我不想减小字体大小 是否有捷径可寻 我不想手动设置刻度 The 最大N定位器 http matplotlib o
  • 将 matplotlib 颜色图集中在特定值上

    我正在使用 matplotlib 颜色图 seismic 绘制绘图 并且希望白色以 0 为中心 当我在不进行任何更改的情况下运行脚本时 白色从 0 下降到 10 我尝试设置 vmin 50 vmax 50 但在这种情况下我完全失去了白色 关
  • 共享辅助轴

    如何使用 matplotlib 中的子图设置共享辅助轴 这是显示问题的最少代码 import numpy as np import matplotlib as mpl import matplotlib pyplot as plt def

随机推荐

  • 如何将一组数组值组合成一个数组? [复制]

    这个问题在这里已经有答案了 我有以下数组 Array 14289 gt Array 0 gt Ability STROKE CLINIC Session Session 3 Tues June 28th Fri July 8th 9 2 0
  • 导致此错误的原因 - “致命错误:无法找到本地 grunt”

    我先删除了旧版本的 grunt 然后安装了新的 grunt 版本 然后出现了这个错误 D www grunt test grunt grunt cli grunt 命令行界面 v0 1 4 致命错误 无法找到本地 grunt 如果您看到此消
  • 在应用程序的生命周期内缓存 IServiceProvider 是否“安全”?

    我正在使用 ASP NET Core 及其内置 DI 容器 我正在使用无法更改的第三方库 NLog My Foo类具有依赖关系 通过构造函数注入 public class Foo private readonly IMyContext co
  • 盒装价值的寿命不够长

    我正在尝试在 Rust 中实现一个缺点列表作为练习 我已经成功解决了除此之外的所有编译器错误 Compiling list v0 0 1 file home nate git rust list home nate git rust lis
  • 为什么迭代 i32 向量会引用 i32 (&i32)?

    以下程序尝试对学生的成绩进行评分 use std io fn main let mut in0 String new io stdin read line mut in0 expect stdin err let n i32 in0 tri
  • WCF 服务返回“不允许的方法”

    在开发我的第一个 WCF 服务的过程中 当我尝试使用它时 我得到 不允许的方法 没有其他解释 我已经使用 ServiceContract 和 OperationContract 设置了界面 OperationContract void Fi
  • mssql 2个日期时间之间的30分钟时间间隔

    我有以下查询 我想获取 2 个日期时间之间 30 分钟间隔的日期时间 基本上我得到了它 但它是有限的 如果时间差超过 24 小时 则不会返回所有结果 例如 DateTime1 24 11 2016 18 00 00 DateTime2 25
  • javascript从多个范围中获取随机数

    我见过不同语言的不同实现 但是我还没有遇到 js 方法 本质上 我希望能够检索提供的范围数组内的随机值 var ranges min 2 max 50 min 500 max 600 etc 我有基本的最小最大函数 只是不知道如何有效地做到
  • 用于测试任何委托性能的通用函数

    当测试不同方法实现的相对性能时 我发现自己重写了与此类似的函数 private static long Measure int iterations Func
  • 当前播放音乐的曲目信息

    我正在实现一个与获取当前音乐曲目信息相关的应用程序 我正在使用以下代码来实现 public class CurrentMusicTrackInfoActivity extends Activity public static final S
  • PHP:Mysqli 用“select *”准备了语句

    这就是我目前从数据库获取的方式 if stmt mysqli gt prepare SELECT fname lname from table name where cno gt LIMIT 50 stmt gt bind param i
  • Dropbox Sync API Android - 更新缓存文件

    我在更新 Android 应用程序中现有的缓存文件时遇到麻烦 for DbxFileInfo fInfo fileList Log d TAG File Path fInfo path toString String fileName fI
  • toLocaleDateString() - 挪威语问题

    我在正确设置区域设置日期字符串格式时遇到问题 它突然停止为挪威语工作 我尝试过 不 不 和 nb 不 关于可能导致这种情况的原因有什么想法吗 我被困住了 Example console log new Date toLocaleDateSt
  • 用数组索引多维数组

    我有一个多维 NumPy 数组 In 1 m np arange 1 26 reshape 5 5 In 2 m Out 2 array 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  • 固定小数精度[重复]

    这个问题在这里已经有答案了 我目前正在使用 std cout precision 5 设置我的输出的小数精度 然而 我宁愿拥有我的 输出总是输出 5 位小数 现在不会显示 0 我将如何更改我的代码以反映这一点 您正在寻找std fixed和
  • Magick++ 链接错误

    我这里有一个使用 Magick ImageMagick 接口 库的简单图像转换器代码 Eclipse IDE include
  • Tableau - 公用表表达式 (CTE) SQL Server

    我正在将 Tableau 与 SQL Server 连接 并尝试使用 T SQL 查询 我只是想知道 Tableau 是否支持 CTE 通用表表达式 我看到这篇文章 它说 CTE 是可能的 http kb tableau com artic
  • 如何使 Doctrine_Expression ( Doctrine 1.2 ) 尝试获取最后 7 天

    我尝试用原则 1 2 进行这个查询 q gt where date gt new Doctrine Expression DATE SUB CURDATE INTERVAL 7 DAY 但它没有给我返回任何结果 任何想法 thanks 它不
  • 如何从字符串中提取浮点数[重复]

    这个问题在这里已经有答案了 我有很多类似的字符串Current Level 13 4 db 我想只提取浮点数 我说的是浮动而不是十进制 因为它有时是整数 RegEx 可以做到这一点还是有更好的方法 如果您的浮点数始终以十进制表示法表示 例如
  • 在 PyQt 中嵌入“图形类型”Seaborn 图(pyqtgraph)

    我正在使用 PyQt 的包装器 pyqtgraph 构建 GUI 应用程序 我希望嵌入一个Seaborn使用其中的绘图MatplotlibWidget 但是 我的问题是 Seaborn 包装方法 例如FacetGrid不接受外部图形句柄 此