如果调用 showGrid,pyqtgraph 会切断刻度标签

Posted

技术标签:

【中文标题】如果调用 showGrid,pyqtgraph 会切断刻度标签【英文标题】:pyqtgraph cuts off tick labels if showGrid is called 【发布时间】:2021-12-17 08:15:00 【问题描述】:

我正在尝试使用pyqtgraph 显示一些子图。 我想在这些图上设置 x 和/或 y 轴范围和网格。 这里是一个没有网格的例子:

import numpy as np
import pyqtgraph as pg


x = np.linspace(0, 2*np.pi, 1000)
y = np.sin(x)


app = pg.mkQApp()

win = pg.GraphicsLayoutWidget(show = True)

p1 = win.addPlot(row = 0, col = 0)
p1.plot(x = x, y = y, pen = pg.mkPen(color = 'b', width = 1))
p1.setXRange(0, 2*np.pi, padding = 0)
p1.setYRange(-1, 1, padding = 0)

app.exec_()

如果我打开网格:

...
p1.showGrid(x = True, y = True)
app.exec_()

然后我得到:

正如您在左下角看到的那样,x 和 y 的第一个刻度被切断了,这个问题只有在我打开网格时才会出现。 如何在不切断轴刻度标签的情况下在我的图上显示网格(并正确设置 x 和 y 限制)?

【问题讨论】:

【参考方案1】:

创建此问题似乎是为了修复 github 上的另一个详细信息:https://github.com/pyqtgraph/pyqtgraph/issues/732

在 pyqtgraph/AxisItem.py 源代码中,如果您散列以下两行(1162、1163),则问题已得到纠正,但工件将再次显示在轴上:

# Draw all text
if self.style['tickFont'] is not None:
    p.setFont(self.style['tickFont'])
p.setPen(self.textPen())

# bounding = self.boundingRect().toAlignedRect()
# p.setClipRect(bounding)        # Ignore Clip
for rect, flags, text in textSpecs:
    p.drawText(rect, int(flags), text)

另一个选项,如 github 问题链接中所列,将仅显示适合边界框的轴刻度(在 AxisItem.py 源中覆盖):

# Draw all text
if self.style['tickFont'] is not None:
    p.setFont(self.style['tickFont'])
p.setPen(self.textPen())

bounding = self.boundingRect()
for rect, flags, text in textSpecs:
    # PATCH: only draw text that completely fits
    if bounding.contains(rect):
        p.drawText(rect, int(flags), text)

我的首选方法是通过“顶部”和“右”轴设置网格,并从刻度标签所在的“左”和“底部”禁用它。试试这个:

import numpy as np
import pyqtgraph as pg

x = np.linspace(0, 2*np.pi, 1000)
y = np.sin(x)

app = pg.mkQApp()
win = pg.GraphicsLayoutWidget(show = True)

p1 = win.addPlot(row = 0, col = 0)
p1.plot(x = x, y = y, pen = pg.mkPen(color = 'b', width = 1))
p1.setXRange(0, 2*np.pi, padding = 0)
p1.setYRange(-1, 1, padding = 0)

p1.showGrid(x = True, y = True)
p1.getAxis('left').setGrid(False)      # Disable left axis grid
p1.getAxis('bottom').setGrid(False)    # Dsiable bottom axis grid

for key in ['right', 'top']:
    p1.showAxis(key)                            # Show top/right axis (and grid, since enabled here)
    p1.getAxis(key).setStyle(showValues=False)  # Hide tick labels on top/right

app.exec_()

结果图:result

在 pyqtgraph/AxisItem.py 源代码的第 581 行,您可以看到如果 'self.grid' 为 True 或 False,则刻度边界矩形的处理方式不同:

def boundingRect(self):
    linkedView = self.linkedView()
    if linkedView is None or self.grid is False:
        rect = self.mapRectFromParent(self.geometry())
        ## extend rect if ticks go in negative direction
        ## also extend to account for text that flows past the edges
        tl = self.style['tickLength']
        if self.orientation == 'left':
            rect = rect.adjusted(0, -15, -min(0, tl), 15)
        elif self.orientation == 'right':
            rect = rect.adjusted(min(0, tl), -15, 0, 15)
        elif self.orientation == 'top':
            rect = rect.adjusted(-15, 0, 15, -min(0, tl))
        elif self.orientation == 'bottom':
            rect = rect.adjusted(-15, min(0, tl), 15, 0)
        return rect
    else:
        return self.mapRectFromParent(self.geometry()) | linkedView.mapRectToItem(self, linkedView.boundingRect())

【讨论】:

我根据您的建议编辑了我的代码,现在一切正常!太感谢了! :-)

以上是关于如果调用 showGrid,pyqtgraph 会切断刻度标签的主要内容,如果未能解决你的问题,请参考以下文章

pyqtgraph / PlotCurveItem 的实时可视化瓶颈

用PyQtGraph绘制可视化数据图表

使用 pyqtgraph 进行实时应用好不好? [复制]

PyQtGraph SpotItem 在调用用户数据时返回“NoneType”

如何更新pyqtgraph中的绘图?

pyqtgraph ImageView 在多线程时冻结