使用Plotly的px.imshow绘制多图像子图报形状错误如何解决?
错误原因
- 触发报错的核心是两个用法问题:
px.imshow()返回的是完整的Figure对象,不是可被add_trace()接收的单条trace对象,不能直接和make_subplots搭配使用- 你传入了包含5张单通道图的三维数组
(5, 1440, 1920),不符合px.imshow()默认仅接收单张2D灰度/3通道RGB/4通道RGBA图的要求
修复方案
有两种常用实现方式,按需选择即可:
方案1:用make_subplots逐张添加图像
使用plotly.graph_objects的Image类作为trace添加到子图中,代码修改如下:
from skimage.morphology import binary_closing, binary_dilation, binary_erosion, binary_opening, selem import plotly.graph_objects as go from plotly.subplots import make_subplots import cv2 import os file = "./../../...zip" image_file = "./../../images" # 注意你原代码漏了img的读取逻辑,自行替换为实际图像路径即可 img = cv2.imread("你的实际图像路径", 0) # 按灰度图读取 img = cv2.convertScaleAbs(img) img = cv2.medianBlur(img, 5) # use a disk of radius 3 selem = selem.disk(3) # opening and closing open_img = binary_opening(img, selem) close_img = binary_closing(img, selem) # erosion and dilation eroded_img = binary_erosion(img, selem) dilated_img = binary_dilation(img, selem) # 定义子图标题 subplot_titles = ["原图", "开运算", "闭运算", "腐蚀", "膨胀"] # 创建3行2列子图 fig = make_subplots(rows=3, cols=2, subplot_titles=subplot_titles) # 逐张添加图像到对应位置 fig.add_trace(go.Image(z=img, colorscale='gray'), row=1, col=1) fig.add_trace(go.Image(z=open_img, colorscale='gray'), row=1, col=2) fig.add_trace(go.Image(z=close_img, colorscale='gray'), row=2, col=1) fig.add_trace(go.Image(z=eroded_img, colorscale='gray'), row=2, col=2) fig.add_trace(go.Image(z=dilated_img, colorscale='gray'), row=3, col=1) # 调整布局后显示 fig.update_layout(height=900, width=1200, title_text="形态学操作效果对比") fig.show()
方案2:直接用px.imshow的facet_col参数自动生成分栏子图
不用手动创建子图,直接传入三维数组,指定分栏参数即可,代码更简洁:
from skimage.morphology import binary_closing, binary_dilation, binary_erosion, binary_opening, selem import plotly.express as px import cv2 import os file = "./../../...zip" image_file = "./../../images" # 自行替换为实际图像路径 img = cv2.imread("你的实际图像路径", 0) img = cv2.convertScaleAbs(img) img = cv2.medianBlur(img, 5) # use a disk of radius 3 selem = selem.disk(3) # opening and closing open_img = binary_opening(img, selem) close_img = binary_closing(img, selem) # erosion and dilation eroded_img = binary_erosion(img, selem) dilated_img = binary_dilation(img, selem) # 把所有图拼成列表,传入px.imshow,指定facet_col按第0维分栏 fig = px.imshow( [img, open_img, close_img, eroded_img, dilated_img], facet_col=0, # 沿第0个维度拆分,每一组作为一个子图 facet_col_wrap=2, # 每行最多放2张子图 color_continuous_scale='gray', title="形态学操作效果对比" ) # 替换默认子图标题为自定义内容 for i, title in enumerate(["原图", "开运算", "闭运算", "腐蚀", "膨胀"]): fig.layout.annotations[i].text = title fig.update_layout(height=900, width=1200) fig.show()
内容的提问来源于stack exchange,提问作者melololo
相关产品推荐
相关产品推荐

