带有 3D 图的 pyqtgraph 子图布局

pyqtgraph subplot layout with 3D plot

我想用以下布局绘制一个 pyqtgraph 子图:

+-----+-----+-----+-----+-----+
|     |     |     |     |     |
+-----+-----+-----+-----+-----+
|                             |
+-----------------------------+
|                             |
+-----------------------------+

3行,只有第一行有5列。
根据的建议,我写了这段代码:

from pyqtgraph.Qt import QtGui
import numpy as np
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import matplotlib.pyplot as plt


cmap = plt.get_cmap('jet')

app = QtGui.QApplication([])
win = pg.GraphicsWindow()
layoutgb = QtGui.QGridLayout()
win.setLayout(layoutgb)

N = 11
M = 11

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, M)

for i in range(5):

    glvw = gl.GLViewWidget()

    z = np.random.random((N, M))

    minZ = np.min(z)
    maxZ = np.max(z)
    colors = cmap((z - minZ)/(maxZ - minZ))
    
    surf = gl.GLSurfacePlotItem(x = x, 
                                y = y, 
                                z = z, 
                                colors = colors, 
                                drawEdges = True)

    glvw.addItem(surf)

    layoutgb.addWidget(glvw, 0, i)

p1 = pg.PlotWidget()
p1.plot([1, 2, 3, 4, 5], [1, 0, 2, 3, 1], pen ='r', name ='red')
layoutgb.addWidget(p1, 1, 0)

p2 = pg.PlotWidget()
p2.plot([1, 2, 3, 4, 5], [2, 1, 4, 1, 1], pen ='g', name ='green')
layoutgb.addWidget(p2, 2, 0)

glvw.sizeHint = lambda: pg.QtCore.QSize(100, 100)
p1.sizeHint = lambda: pg.QtCore.QSize(100, 100)
p2.sizeHint = lambda: pg.QtCore.QSize(100, 100)
glvw.setSizePolicy(p1.sizePolicy())

QtGui.QApplication.instance().exec_()

如您所见,上述代码生成的子图有两个主要问题:

  1. 即使代码确实生成了 5 个 3D GLSurfacePlotItem,它也只绘制了 2 个
  2. PlotWidget p1p2 未拉伸到完整的 window 宽度

我不知道如何解决第一个问题。关于第二个,我尝试按照的建议来解决它,但我没有得到任何结果。

任何帮助都会有所帮助。

  1. 即使代码确实生成了 5 个 3D GLSurfacePlotItem,它也只绘制了 2 个

我通过更改 gl.GLViewWidgetQSize 来解决这个问题:

glvw.sizeHint = lambda: pg.QtCore.QSize(100, 500)
  1. PlotWidget p1p2 未拉伸到完整的 window 宽度

我通过在 addWidget 方法中指定 rowSpancolumnSpan 参数来解决这个问题:

layoutgb.addWidget(p1, 1, 0, 1, -1)
...
layoutgb.addWidget(p2, 2, 0, 1, -1)

完整代码

from pyqtgraph.Qt import QtGui#, QtCore
import numpy as np
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import matplotlib.pyplot as plt


cmap = plt.get_cmap('jet')

app = QtGui.QApplication([])
win = pg.GraphicsWindow()
layoutgb = QtGui.QGridLayout()
win.setLayout(layoutgb)

N = 11
M = 11

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, M)

for i in range(5):

    glvw = gl.GLViewWidget()

    z = np.random.random((N, M))

    minZ = np.min(z)
    maxZ = np.max(z)
    colors = cmap((z - minZ)/(maxZ - minZ))
    
    surf = gl.GLSurfacePlotItem(x = x, 
                                y = y, 
                                z = z, 
                                colors = colors, 
                                drawEdges = True)

    glvw.addItem(surf)

    layoutgb.addWidget(glvw, 0, i)

p1 = pg.PlotWidget()
p1.plot([1, 2, 3, 4, 5], [1, 0, 2, 3, 1], pen ='r', name ='red')
layoutgb.addWidget(p1, 1, 0, 1, -1)

p2 = pg.PlotWidget()
p2.plot([1, 2, 3, 4, 5], [2, 1, 4, 1, 1], pen ='g', name ='green')
layoutgb.addWidget(p2, 2, 0, 1, -1)

glvw.sizeHint = lambda: pg.QtCore.QSize(100, 500)

QtGui.QApplication.instance().exec_()