使用pyqtgraph绘制半导体晶圆图遇IndexError问题求助
问题与解决方案:PyQtGraph绘制半导体晶圆图的IndexError及替代方案
问题描述
尝试用PyQtGraph的PColorMeshItem绘制由数千个不同颜色、坐标方块组成的半导体晶圆图,并实现悬停/点击事件,但运行时触发IndexError。
代码示例
''' Demonstrates very basic use of PColorMeshItem ''' import numpy as np import pyqtgraph as pg app = pg.mkQApp("PColorMesh Example") ## Create window with GraphicsView widget win = pg.GraphicsLayoutWidget() win.show() ## show widget alone in its own window win.setWindowTitle('pyqtgraph example: pColorMeshItem') view = win.addViewBox() ## Create data x_min = 0 x_max = 2 y_min = 0 y_max = 2 x = np.arange(x_min, x_max+2, 1, dtype=np.int16) y = np.arange(y_min, y_max+2, 1, dtype=np.int16) xmesh, ymesh = np.meshgrid(x, y, indexing='xy') # init with all np.nan to hide all squares z = np.full((y.size-1, x.size-1), np.nan) # fill data in specific area z[(1, 1, 1), (0, 1, 2)] = 1 z[(0, 1, 2), (1, 1, 1)] = 1 pcmi = pg.PColorMeshItem(xmesh, ymesh, z) view.addItem(pcmi) if __name__ == '__main__': pg.exec()
错误信息
File "/usr/local/lib/python3.9/site-packages/pyqtgraph/graphicsItems/PColorMeshItem.py", line 139, in __init__ self.setData(*args) File "/usr/local/lib/python3.9/site-packages/pyqtgraph/graphicsItems/PColorMeshItem.py", line 258, in setData brushes = [lut[z] for z in norm[i].tolist()] File "/usr/local/lib/python3.9/site-packages/pyqtgraph/graphicsItems/PColorMeshItem.py", line 258, in <listcomp> brushes = [lut[z] for z in norm[i].tolist()] IndexError: list index out of range
norm数组内容
[[-9223372036854775808 -9223372036854775808 -9223372036854775808] [-9223372036854775808 -9223372036854775808 -9223372036854775808] [-9223372036854775808 -9223372036854775808 -9223372036854775808]]
错误原因与修复
原因分析
错误源于z数组中混合了np.nan和整数1,PColorMeshItem处理时会将np.nan转换为极小整数(即norm数组中的-9223372036854775808),而默认颜色查找表(LUT)长度不足,导致索引越界。
修复步骤
- 显式指定颜色映射范围:确保
z的有效值落在颜色映射索引范围内,同时处理np.nan的显示。 - 设置自定义颜色查找表(LUT):或直接指定
levels参数,让PyQtGraph自动生成适配的LUT。
修改后的代码示例:
''' Fixed PColorMeshItem Example ''' import numpy as np import pyqtgraph as pg app = pg.mkQApp("PColorMesh Example") win = pg.GraphicsLayoutWidget() win.show() win.setWindowTitle('pyqtgraph example: pColorMeshItem') view = win.addViewBox() ## Create data x_min = 0 x_max = 2 y_min = 0 y_max = 2 x = np.arange(x_min, x_max+2, 1, dtype=np.int16) y = np.arange(y_min, y_max+2, 1, dtype=np.int16) xmesh, ymesh = np.meshgrid(x, y, indexing='xy') z = np.full((y.size-1, x.size-1), np.nan) # fill data in specific area z[(1, 1, 1), (0, 1, 2)] = 1 z[(0, 1, 2), (1, 1, 1)] = 1 # 显式设置levels,指定z的有效值范围,同时让nan透明 pcmi = pg.PColorMeshItem(xmesh, ymesh, z, levels=[0, 2], antialias=False) # 可选:自定义颜色映射 # cmap = pg.colormap.get('viridis') # pcmi.setColorMap(cmap) view.addItem(pcmi) if __name__ == '__main__': pg.exec()
也可以将z中的np.nan替换为有效值范围外的数值(比如-1),再通过levels排除该值的显示,效果一致。
绘制半导体晶圆图的其他方案
- 使用
ImageItem:如果晶圆方块是规则网格排列,ImageItem渲染效率更高,支持快速交互。只需将z数组作为图像数据传入,设置颜色映射即可,通过MouseEvents实现悬停/点击事件。 - 使用
ScatterPlotItem:如果方块是非规则分布,可用ScatterPlotItem绘制正方形标记,通过sizes控制方块大小,brush设置颜色。这种方式灵活度高,适合非规则布局的晶圆图,交互事件易实现。 - 自定义
GraphicsItem:针对高度定制化需求(如复杂交互逻辑、特殊渲染效果),可继承pyqtgraph.GraphicsObject自定义绘图项,在paint方法中直接绘制每个方块,完全控制渲染和交互行为。
内容的提问来源于stack exchange,提问作者nochenon
相关产品推荐
相关产品推荐

