李玖泽 2024-04-02 04:29 采纳率: 0%
浏览 103
已结题

在pyside6界面的seaborn(matplotlib)聚类图的工具栏使用问题

在将seaborn(matplotlib)聚类图嵌入到pyside6界面时,因为正常使用matplotlib都会有工具栏,想再添加个工具栏的功能,一开始在前面实例了工具栏,但是点击放大按钮光标都无法变成十字光标,所以我在绘制热图之后进行工具栏的绑定,但是确实是在界面绑定了,也能捕获到光标所在坐标,但是当我点击放大功能时,光标是变成了十字光标,但是无法选中一片区域,也就无法进行放大功能,工具栏的其他功能要么没有作用,但是border设置完了之后,需要重新拉伸窗体刷新热图才能更新成功,请解惑。

# coding:utf-8

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qtagg import NavigationToolbar2QT
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton

from optimal_ref_ordering import optimal_ref_plus

class MplCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        super(MplCanvas, self).__init__(fig)


class HeatmapInterface(QWidget):
    def __init__(self, shared_variables, parent=None):
        super().__init__(parent=parent)
        self.shared_variables = shared_variables

        self.initUi()

        self.btn_heatmap = QPushButton('生成热图', self)
        # 创建 FigureCanvas
        self.canvas = FigureCanvas(plt.figure())
        #self.canvas.resize(760, 738)
        #self.setCentralWidget(self.canvas)
        # self.toolbar = NavigationToolbar2QT(self.canvas, self)  # 创建绘图工具条

        # 创建布局并添加 FigureCanvas
        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.btn_heatmap)
        #self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas)

        self.setLayout(self.layout)

        # leave some space for title bar
        self.layout.setContentsMargins(0, 32, 0, 8)

        self.btn_heatmap.clicked.connect(self.generate_heatmap)

        self.resize(790, 768)


    def initUi(self):
        self.opt_pattern_linkage = None

    def generate_heatmap(self):
        print('heatmapinterface',self.shared_variables['scaledata'],
                                                    self.shared_variables['cluster_method'],
                                                    self.shared_variables['distance'],
                                                    self.shared_variables['ref_sample'],'allall')
        self.opt_pattern_linkage = optimal_ref_plus(self.shared_variables['scaledata'],
                                                    method=self.shared_variables['cluster_method'],
                                                    metric=self.shared_variables['distance'],
                                                    ref=self.shared_variables['ref_sample'])

        # 调用热力图生成函数,这里使用了虚构的 optimal_ref_plus 函数
        heatmap = sns.clustermap(self.shared_variables['scaledata'],
                                 method=self.shared_variables['cluster_method'],
                                 metric=self.shared_variables['distance'],
                                 col_linkage=self.opt_pattern_linkage,
                                 # 使用matplotlib中的颜色盘
                                 cmap=plt.get_cmap('bwr'),
                                 cbar_pos=(0.03, 0.82, 0.05, 0.16),  # cbar_pos:图例位置、宽、高设置(left, bottom, width, height)
                                 )

        # 清除之前的图形
        self.canvas.figure.clear()

        # 将生成的热力图绘制在 FigureCanvas 上
        self.canvas.figure = heatmap.fig
        self.canvas.draw()

        # 创建新的工具条并将其与 FigureCanvas 关联
        self.toolbar = NavigationToolbar2QT(self.canvas, self)

        self.layout.addWidget(self.toolbar)


if __name__ == "__main__":
    app = QApplication([])
    default_filepath = 'C:/Users/Muzier/Desktop/data-carpentry-rnaseq-master/data/counts_transformed.csv'
    rawdata = pd.read_csv(default_filepath, index_col=0)
    object = {'scaledata': rawdata, 'cluster_method': 'complete', 'distance': 'euclidean', 'ref_sample': 'wt_60_r1'}
    window = HeatmapInterface(object)
    window.show()
    app.exec()



  • 写回答

16条回答 默认 最新

  • 檀越@新空间 2024-04-02 04:29
    关注

    上午好☀️☀️☀️️
    本答案参考ChatGPT-3.5

    根据你的描述,你想要在PySide6界面上嵌入seaborn(matplotlib)的聚类图,并添加一个自定义的工具栏来实现一些功能,但是遇到了几个问题。你想在绘制热图之后进行工具栏的绑定,但是发现放大功能不起作用,光标变成了十字光标,但是无法选中区域进行放大。此外,工具栏的其他功能也无法正常使用。

    针对这些问题,我提供以下解决方案:

    1. 创建绘图工具条时,将它绑定到FigureCanvas之前。通过这样做,工具栏会在热图绘制之前创建,并且可以正确地处理放大功能。

    2. 确保FigureCanvas具有正确的尺寸。如果FigureCanvas没有正确的尺寸,可能会导致光标无法选择区域进行放大。你可以手动为FigureCanvas设置尺寸,或者使用self.canvas.setGeometry()方法将其尺寸与布局兼容。

    3. 在更新热图之后,手动调用self.canvas.draw()方法重新绘制FigureCanvas。这将确保热图变化被正确显示在界面上。

    根据上述解决方案,在你的代码中进行了一些修改。以下是修改后的代码:

    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    from matplotlib.backends.backend_qtagg import NavigationToolbar2QT
    from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.figure import Figure
    from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton
    
    from optimal_ref_ordering import optimal_ref_plus
    
    class HeatmapInterface(QWidget):
        def __init__(self, shared_variables, parent=None):
            super().__init__(parent=parent)
            self.shared_variables = shared_variables
            self.initUi()
    
            self.btn_heatmap = QPushButton('生成热图', self)
    
            # 创建 FigureCanvas
            self.canvas = FigureCanvas(plt.figure())
    
            # 创建绘图工具条并绑定到FigureCanvas
            self.toolbar = NavigationToolbar2QT(self.canvas, self) 
    
            # 创建布局并添加 FigureCanvas 和工具条
            self.layout = QVBoxLayout(self)
            self.layout.addWidget(self.btn_heatmap)
            self.layout.addWidget(self.toolbar)
            self.layout.addWidget(self.canvas)
            self.setLayout(self.layout)
    
            # leave some space for title bar
            self.layout.setContentsMargins(0, 32, 0, 8)
    
            self.btn_heatmap.clicked.connect(self.generate_heatmap)
    
            self.resize(790, 768)
    
        def initUi(self):
            self.opt_pattern_linkage = None
    
        def generate_heatmap(self):
            self.opt_pattern_linkage = optimal_ref_plus(self.shared_variables['scaledata'],
                                                        method=self.shared_variables['cluster_method'],
                                                        metric=self.shared_variables['distance'],
                                                        ref=self.shared_variables['ref_sample'])
    
            # 调用热力图生成函数,这里使用了虚构的 optimal_ref_plus 函数
            heatmap = sns.clustermap(self.shared_variables['scaledata'],
                                     method=self.shared_variables['cluster_method'],
                                     metric=self.shared_variables['distance'],
                                     col_linkage=self.opt_pattern_linkage,
                                     cmap=plt.get_cmap('bwr'),
                                     cbar_pos=(0.03, 0.82, 0.05, 0.16),
                                     )
    
            # 更新FigureCanvas
            self.canvas.draw()
    
    if __name__ == "__main__":
        app = QApplication([])
        default_filepath = 'C:/Users/Muzier/Desktop/data-carpentry-rnaseq-master/data/counts_transformed.csv'
        rawdata = pd.read_csv(default_filepath, index_col=0)
        object = {'scaledata': rawdata, 'cluster_method': 'complete', 'distance': 'euclidean', 'ref_sample': 'wt_60_r1'}
        window = HeatmapInterface(object)
        window.show()
        app.exec()
    

    请注意,修改后的代码将工具栏的创建移动到了FigureCanvas之前,并在更新热图之后手动重新绘制了FigureCanvas。如果你仍然遇到问题,请让我知道。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月2日
  • 修改了问题 4月2日
  • 赞助了问题酬金15元 4月2日
  • 创建了问题 4月2日