如何调整PyQtGraph图例的对齐方式并固定在组件右侧?
解决PyQtGraph图例固定在组件右侧的问题
方法1:利用QGraphicsLayout手动布局
PyQtGraph的图例本质是QGraphicsWidget,可以通过QGraphicsGridLayout将图表视图和图例放在同一行,让图例自动靠右对齐,窗口大小变化时会自动适配位置,无需手动计算偏移。
示例代码:
import pyqtgraph as pg from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout app = QApplication([]) win = QMainWindow() central_widget = QWidget() win.setCentralWidget(central_widget) layout = QVBoxLayout(central_widget) # 创建PlotWidget并添加曲线 plot = pg.PlotWidget() curve1 = plot.plot([1,2,3,4], [1,4,9,16], name="曲线1") curve2 = plot.plot([1,2,3,4], [2,5,10,17], name="曲线2") # 移除默认图例,避免重复显示 legend = plot.legend plot.scene().removeItem(legend) # 创建布局,将视图和图例横向排列 graph_layout = pg.GraphicsLayout() view_box = plot.getViewBox() graph_layout.addItem(view_box, 0, 0) graph_layout.addItem(legend, 0, 1) # 将布局加入PlotWidget场景 plot.scene().addItem(graph_layout) layout.addWidget(plot) win.show() app.exec_()
方法2:重写LegendItem的位置更新逻辑
自定义LegendItem类,重写updateGeometry方法,让图例始终基于父容器(ViewBox)的尺寸自动靠右对齐,彻底摆脱手动设置offset的繁琐。
示例代码:
import pyqtgraph as pg from PyQt5.QtCore import Qt class RightAlignedLegend(pg.LegendItem): def updateGeometry(self): super().updateGeometry() view_box = self.parentItem() if not view_box: return # 获取视图区域和图例自身尺寸 view_rect = view_box.viewRect() legend_rect = self.boundingRect() # 计算靠右且垂直居中的位置 x_pos = view_rect.right() - legend_rect.width() - 10 # 10为右侧留白 y_pos = view_rect.center().y() - legend_rect.height()/2 self.setPos(x_pos, y_pos) # 使用自定义图例 app = pg.mkQApp() plot = pg.PlotWidget() curve1 = plot.plot([1,2,3], [4,5,6], name="曲线A") curve2 = plot.plot([1,2,3], [7,8,9], name="曲线B") # 替换默认图例 plot.legend = RightAlignedLegend() plot.legend.setParentItem(plot.getViewBox()) plot.legend.addItem(curve1, curve1.name()) plot.legend.addItem(curve2, curve2.name()) plot.show() app.exec_()
方法3:监听resize信号动态调整offset
如果不想修改图例类,可以给PlotWidget安装事件过滤器,监听窗口resize事件,实时计算并更新图例的offset值。
示例代码:
import pyqtgraph as pg from PyQt5.QtCore import QEvent app = pg.mkQApp() plot = pg.PlotWidget() curve1 = plot.plot([1,2,3], [1,4,9], name="曲线X") curve2 = plot.plot([1,2,3], [2,5,10], name="曲线Y") legend = plot.legend def adjust_legend_pos(event): if event.type() == QEvent.Resize: view_rect = plot.getViewBox().viewRect() legend_width = legend.boundingRect().width() # 计算基于左轴的偏移量:视图宽度 - 图例宽度 - 边距 offset_x = view_rect.width() - legend_width - 10 legend.setOffset((offset_x, 0)) # y轴可按需调整为居中或固定值 plot.installEventFilter(plot) plot.eventFilter = adjust_legend_pos plot.show() app.exec_()
三种方法各有适用场景:方法1的布局方式最稳定,无需复杂计算;方法2适合需要多次复用右侧对齐图例的场景;方法3是轻量级修改,适合快速适配现有代码。
内容的提问来源于stack exchange,提问作者Bartosz
相关产品推荐
相关产品推荐

