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

pyqtgraph cuts off tick labels if showGrid is called

我正在尝试使用 pyqtgraph 显示一些子图。
我想在这些图上设置 x and/or 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 限制)?

创建此问题似乎是为了修复 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 问题 link 中列出的另一个选项是仅显示适合边界框的轴刻度(在 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)

我的首选方法是通过 'top' 和 'right' 轴设置网格,并在刻度标签所在的 'left' 和 'bottom' 禁用它.试一试:

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())