2026/9/21 16:03:07

Plotly.py 图像图层完全指南:在图表中添加背景图、Logo 与注释图像

Plotly.py 图像图层完全指南:在图表中添加背景图、Logo 与注释图像 数据可视化数据分析【免费下载链接】plotly.pyThe interactive graphing library for Python :sparkles:项目地址https://gitcode.com/gh_mirrors/pl/plotly.py点击查看免费下载本文基于 Plotly.py 官方教程 images.md 编写讲解如何在交互式图表中嵌入静态、非交互的图片包括背景图、品牌 Logo、数据标注图以及可缩放图像等场景。阅读完本文你将掌握fig.add_layout_image与fig.update_layout_images的完整用法、go.layout.Image全部属性的取值语义并能结合源码理解图片的底层序列化机制。说明本文中所有代码示例均继承自 images.md属性取值与默认值描述则以仓库内自动生成的 layout/_image.py 及 basevalidators.py 源码为准。一、核心概念静态图片与layout.imagesPlotly.py 中的图片image指添加到图表布局layout上的静态、非交互位图常用于三类场景背景图作为整张图表的底图铺在绘图区域Logo将品牌标识放在图表角落注释图将分子结构图、示意图等作为标注挂在数据点附近。与之相对如果需要交互式地探索图像数据如鼠标悬停读取像素值应使用 imshow 教程位于plotly/express/_imshow.py中的px.imshow它会把图像作为数据 trace 处理而不是本文讨论的布局图片。在 Plotly 的图对象体系中图片由go.layout.Image表示存放于Figure.layout.images数组。该类的全部合法属性定义在仓库自动生成的 layout/_image.py 中_valid_props { layer, name, opacity, sizex, sizey, sizing, source, templateitemname, visible, x, xanchor, xref, y, yanchor, yref, }添加图片有两种等价方式调用fig.add_layout_image(...)方法定义见 _figure.py或在构造/更新布局时直接赋值go.Layout(images[...])。推荐使用前者因为它支持按子图行/列row/col精确挂载图片。二、添加背景图最小可用示例背景图的添加方式使用fig.add_layout_image将图片加入布局或直接设置go.Layout的images参数go.layout.Image的source属性可以是图片 URL也可以是 PIL Image 对象from PIL import Image; img Image.open(filename.png)。下面是一个完整示例在一张散点图下方叠加半透明背景图。import plotly.graph_objects as go # Create figure fig go.Figure() # Add trace fig.add_trace( go.Scatter(x[0, 0.5, 1, 2, 2.2], y[1.23, 2.5, 0.42, 3, 1]) ) # Add images fig.add_layout_image( dict( sourcehttps://images.plot.ly/language-icons/api-home/python-logo.png, xrefx, yrefy, x0, y3, sizex2, sizey2, sizingstretch, opacity0.5, layerbelow) ) # Set templates fig.update_layout(templateplotly_white) fig.show()关键参数解读属性语义详见 layout/_image.py属性取值语义sourceURL 字符串 / data URI / PIL Image图片来源详见下文source 的三种合法形式xref/yrefpaper或轴 id如x、x2可加 domain后缀坐标参照系paper表示相对绘图区域归一化坐标0 左/下、1 右/上轴 id 表示数据坐标轴 id domain表示轴域内归一化坐标x/y任意数值图片锚点位置单位取决于xref/yrefsizex/sizey数值图片容器横向/纵向尺寸。xref为paper时相对绘图宽度xref以domain结尾时相对轴宽度sizingfill/contain/stretch图片在容器内的约束方式fill保持纵横比并尽量填满、contain保持纵横比完整容纳、stretch拉伸填满容器不保持纵横比opacity[0, 1]的数值图片不透明度0 全透明1 不透明layerbelow/above绘制层级below表示画在 trace 下方背景above画在 trace 上方。当xref与yref均为paper时图片绘制在整块绘图区域之下xanchor/yanchorleft/center/right、top/middle/bottom锚点对齐方式决定x/y相对于图片自身的位置visibleTrue/False是否显示该图片name/templateitemname字符串供模板系统使用模板中的命名项会复制到输出图可通过templateitemname引用并覆盖含visible: false隐藏source 的三种合法形式source属性的校验与转换由_plotly_utils/basevalidators.py中的ImageUriValidator负责basevalidators.py其支持远程图片 URI 字符串如https://example.com/image.pngURL 必须从运行绘图代码的域可访问可以是相对或绝对地址data URI 字符串如data:image/png;base64,iVBORw0KGgoAAAANSU适合将图片直接内嵌进图表 JSON无需网络请求PIL.Image.Image 对象若环境中安装了 Pillow传入PIL.Image.open(...)的结果会被立即转换为 PNG data URI。底层转换逻辑非常直观源码见 basevalidators.pystaticmethod def pil_image_to_uri(v): in_mem_file io.BytesIO() v.save(in_mem_file, formatPNG) in_mem_file.seek(0) img_bytes in_mem_file.read() base64_encoded_result_bytes base64.b64encode(img_bytes) base64_encoded_result_str base64_encoded_result_bytes.decode(ascii) v data:image/png;base64,{base64_encoded_result_str}.format(...) return v也就是说只要PIL可导入Image.open(filename.png)得到的对象就会被validate_coerce自动编码为data:image/png;base64,...字符串后再进入图表数据。这意味着本地图片可以直接嵌入图表 JSON非常适合静态导出、Dash 部署或离线环境。三、添加 Logopaper 坐标与锚点对齐将 Logo 放在图表外部的角落时推荐使用xrefpaper、yrefpaper此时x/y的取值范围为[0, 1]其中(0, 0)对应绘图区域左下角(1, 1)对应右上角。配合xanchor/yanchor可让 Logo 精准吸附到角上。以下示例为一幅横向条形图在右上方叠加 Logoimport plotly.graph_objects as go fig go.Figure() fig.add_trace( go.Bar( x[-35.3, -15.9, -15.8, -15.6, -11.1, -9.6, -9.2, -3.5, -1.9, -0.9, 1.0, 1.4, 1.7, 2.0, 2.8, 6.2, 8.1, 8.5, 8.5, 8.6, 11.4, 12.5, 13.3, 13.7, 14.4, 17.5, 17.7, 18.9, 25.1, 28.9, 41.4], y[Designers, musicians, artists, etc., Secretaries and administrative assistants, Waiters and servers, Archivists, curators, and librarians, Sales and related, Childcare workers, home car workers, etc., Food preparation occupations, Janitors, maids, etc., Healthcare technicians, assistants. and aides, Counselors, social and religious workers, Physical, life and social scientists, Construction, Factory assembly workers, Machinists, repairmen, etc., Media and communications workers, Teachers, Mechanics, repairmen, etc., Financial analysts and advisers, Farming, fishing and forestry workers, Truck drivers, heavy equipment operator, etc., Accountants and auditors, Human resources, management analysts, etc., Managers, Lawyers and judges, Engineers, architects and surveyors, Nurses, Legal support workers, Computer programmers and system admin., Police officers and firefighters, Chief executives, Doctors, dentists and surgeons], markergo.bar.Marker( colorrgb(253, 240, 54), linedict(colorrgb(0, 0, 0), width2) ), orientationh, ) ) # Add image fig.add_layout_image( dict( sourcehttps://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png, xrefpaper, yrefpaper, x1, y1.05, sizex0.2, sizey0.2, xanchorright, yanchorbottom ) ) # update layout properties fig.update_layout( autosizeFalse, height800, width700, bargap0.15, bargroupgap0.1, barmodestack, hovermodex, margindict(r20, l300, b75, t125), title(Moving Up, Moving Downbr iPercentile change in income between childhood and adulthood/i), ) fig.show()这里x1, y1.05, xanchorright, yanchorbottom的含义是以绘图区域右边界为基准把 Logo 的右下角锚点放在横向坐标 1、纵向坐标 1.05 处略微超出绘图区域顶部。当xref/yref为paper时sizex0.2表示 Logo 宽度为绘图区域宽度的 20%因此尺寸会随画布大小等比缩放。四、标注光谱数据多图叠加与批量更新对于科学数据可视化常需要在谱图的关键位置放置分子结构图等注释图片。技巧是先逐张添加图片再用update_layout_images批量统一坐标参照。import plotly.graph_objects as go import numpy as np np.random.seed(1) from scipy.signal import savgol_filter # Simulate spectroscopy data def simulated_absorption(mu, sigma, intensity): data [np.random.normal(mu[i], sigma[i], intensity[i]) for i in range(len(mu))] hists [np.histogram(d, 1000, range(200, 500), densityTrue) for d in data] ys [y for y, x in hists] s savgol_filter(np.max(ys, axis0), 41, 3) return hists[0][1], s mus [[290, 240, 260], [330, 350]] sigmas [[4, 6, 10], [5, 4]] intensities [[100000, 300000, 700000], [40000, 20000]] simulated_absorptions [simulated_absorption(m, s, i) for m, s, i in zip(mus, sigmas, intensities)] # Create figure fig go.Figure() # Create traces from data names [Benzene, Naphthalene] for (x, y), n in zip(simulated_absorptions, names): fig.add_trace(go.Scatter(xx, yy, namen)) # Add images fig.add_layout_image( dict( sourcehttps://raw.githubusercontent.com/michaelbabyn/plot_data/master/benzene.png, x0.75, y0.65, )) fig.add_layout_image(dict( sourcehttps://raw.githubusercontent.com/michaelbabyn/plot_data/master/naphthalene.png, x0.9, y0.3, ) ) fig.update_layout_images(dict( xrefpaper, yrefpaper, sizex0.3, sizey0.3, xanchorright, yanchorbottom )) # Add annotations fig.update_layout( annotations[ dict( x93.0 / 300, y0.07 / 0.1, xrefpaper, yrefpaper, showarrowTrue, arrowhead0, opacity0.5, ax250, ay-40, ), dict( x156.0 / 300, y0.04 / 0.1, xrefpaper, yrefpaper, showarrowTrue, arrowhead0, opacity0.5, ax140, ay-10, ) ] ) # Configure axes fig.update_xaxes(title_textWavelength) fig.update_yaxes(title_textAbsorption, hoverformat.3f) # Configure other layout properties fig.update_layout( title_textAbsorption Frequencies of Benzene and Naphthalene, height500, width900, templateplotly_white ) fig.show()该示例的要点两次add_layout_image仅指定了source、x、y此时默认参照数据坐标随后fig.update_layout_images(dict(...))对所有已添加的图片统一施加xrefpaper、yrefpaper、sizex0.3等属性把两张图统一改为 paper 坐标并统一尺寸——这正是update_layout_images的批量能力再配合annotations添加指向峰位的箭头标注形成完整的谱图 结构式标注面板。从源码看update_layout_images_figure.py内部通过_select_annotations_like(propimages, ...)选中图片后逐一调用obj.update(patch, **kwargs)它支持selector、row、col、secondary_y等过滤条件可以只批量更新某一行/列的图片。五、静态图片的缩放与平移轴坐标 隐形锚点 trace需要让用户对图片进行缩放zoom和平移pan时关键技巧是为图片设置数据坐标参照并添加一条不可见的散点 trace 作为自动缩放autoresize的锚点。因为只有存在 trace 时Plotly 的自动布局逻辑才能正确推导坐标范围。import plotly.graph_objects as go # Create figure fig go.Figure() # Constants img_width 1600 img_height 900 scale_factor 0.5 # Add invisible scatter trace. # This trace is added to help the autoresize logic work. fig.add_trace( go.Scatter( x[0, img_width * scale_factor], y[0, img_height * scale_factor], modemarkers, marker_opacity0 ) ) # Configure axes fig.update_xaxes( visibleFalse, range[0, img_width * scale_factor] ) fig.update_yaxes( visibleFalse, range[0, img_height * scale_factor], # the scaleanchor attribute ensures that the aspect ratio stays constant scaleanchorx ) # Add image fig.add_layout_image( dict( x0, sizeximg_width * scale_factor, yimg_height * scale_factor, sizeyimg_height * scale_factor, xrefx, yrefy, opacity1.0, layerbelow, sizingstretch, sourcehttps://raw.githubusercontent.com/michaelbabyn/plot_data/master/bridge.jpg) ) # Configure other layout fig.update_layout( widthimg_width * scale_factor, heightimg_height * scale_factor, margin{l: 0, r: 0, t: 0, b: 0}, ) # Disable the autosize on double click because it adds unwanted margins around the image # More detail: https://plotly.com/python/configuration-options/ fig.show(config{doubleClick: reset})实现细节xrefx、yrefy使图片锚定在数据坐标上因此缩放/平移轴时图片会同步移动scaleanchorx保证 x/y 轴等比例缩放维持图片纵横比不变sizingstretch将图片拉伸填满sizex × sizey指定的容器这里正好等于图像分辨率 ×scale_factorconfig{doubleClick: reset}关闭双击自动缩放带来的额外边距让图像始终贴满画布隐形 trace 的坐标范围即图片范围确保缩放时比例正确。六、在图片上绘制形状机器学习标注与图像分割该能力自 Plotly 4.7 引入对应仓库 CHANGELOG.md 中的版本记录。在图像上叠加形状矩形框、直线等非常实用典型场景包括突出图中物体、为机器学习训练集绘制包围盒bounding box、为分割算法标注种子点。启用形状绘制需要两个条件设置拖拽模式dragmode为对应的绘图工具drawline、drawopenpath、drawclosedpath、drawcircle或drawrect在 modebar 添加绘图按钮通过config{modeBarButtonsToAdd: [...]}加入对应的绘图工具按钮。新形状的样式由布局属性newshape指定形状绘制完成后仍可选中与修改。绘制或修改形状会触发relayout事件该事件可在 Dash 应用中通过回调捕获详见 shapes 教程 中关于在笛卡尔图上绘制形状一节以及仓库内 shapeannotation.py 的形状辅助实现。import plotly.graph_objects as go fig go.Figure() # Add image img_width 1600 img_height 900 scale_factor 0.5 fig.add_layout_image( x0, sizeximg_width, y0, sizeyimg_height, xrefx, yrefy, opacity1.0, layerbelow, sourcehttps://raw.githubusercontent.com/michaelbabyn/plot_data/master/bridge.jpg ) fig.update_xaxes(showgridFalse, range(0, img_width)) fig.update_yaxes(showgridFalse, scaleanchorx, range(img_height, 0)) # Line shape added programatically fig.add_shape( typeline, xrefx, yrefy, x0650, x11080, y0380, y1180, line_colorcyan ) # Set dragmode and newshape properties; add modebar buttons fig.update_layout( dragmodedrawrect, newshapedict(line_colorcyan), title_textDrag to add annotations - use modebar to change drawing tool ) fig.show(config{modeBarButtonsToAdd:[drawline, drawopenpath, drawclosedpath, drawcircle, drawrect, eraseshape ]})注意这里fig.update_yaxes(range(img_height, 0))将 y 轴倒置使图像坐标与屏幕坐标一致左上角为原点更符合图像标注的直觉。七、相对轴域放置图片x domain/y domain使用xrefx domain或yrefy domain可以把图片放在某个子图轴域的相对位置上。此时x1表示轴域右边界y1表示轴域上边界尺寸sizex0.2表示轴域宽度的 20%——图片会随轴域一起平移缩放。以下示例用px.scatter生成按物种分面的鸢尾花散点图并为每个子图右上角放置对应的鸢尾花照片import plotly.express as px df px.data.iris() fig px.scatter(df, xsepal_length, ysepal_width, facet_colspecies) # sources of images sources [ https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Iris_setosa_var._setosa_%282595031014%29.jpg/360px-Iris_setosa_var._setosa_%282595031014%29.jpg, https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Iris_versicolor_quebec_1.jpg/320px-Iris_versicolor_quebec_1.jpg, https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Iris_virginica_2.jpg/480px-Iris_virginica_2.jpg, ] # add images for col, src in enumerate(sources): fig.add_layout_image( row1, colcol 1, sourcesrc, xrefx domain, yrefy domain, x1, y1, xanchorright, yanchortop, sizex0.2, sizey0.2, ) fig.show()这里row1, colcol1把图片精确挂到对应子图x1, y1, xanchorright, yanchortop将图片右上角对齐子图右上角。add_layout_image的row/col参数要求图由plotly.subplots.make_subplots或px分面创建且内部通过_add_annotation_like完成子图定位见 _figure.py。关于xref/yref的取值语法源码给出了精确约束layout/_image.py枚举值paper或匹配正则^x([2-9]|[1-9][0-9])?( domain)?$y 轴同理即x、x2、x10、x domain、x2 domain等组合。八、参考属性速查与底层实现小结go.layout.Image完整属性速查属性定义与 docstring 见 layout/_image.py属性类型/枚举说明source字符串 / data URI / PIL Image图片来源URL 必须从运行绘图代码的域可访问xrefpaper或^x([2-9]\|[1-9][0-9])?( domain)?$x 坐标参照系yrefpaper或^y(...)( domain)?$y 坐标参照系x/y任意类型图片锚点坐标sizex/sizey数值容器尺寸单位随xref/yref变化sizingfill/contain/stretch容器内适配策略opacity[0, 1]不透明度layerbelow/above相对 trace 的绘制层级xanchorleft/center/rightx 锚点对齐yanchortop/middle/bottomy 锚点对齐visible布尔是否显示name/templateitemname字符串模板命名引用模板机制见 templates 教程底层实现要点对应仓库源码API 入口add_layout_image在内部构造layout.Image实例并调用_add_annotation_like挂载_figure.pyupdate_layout_images通过_select_annotations_like(propimages, ...)选择后批量update_figure.pysource 校验ImageUriValidator.validate_coerce负责将 PIL Image 即时转换为 PNG base64 data URI_plotly_utils/basevalidators.py子图定位row/col/secondary_y/exclude_empty_subplots参数由_add_annotation_like处理相关行为在 tests/test_core/test_update_objects/test_update_annotations.py 中有覆盖测试测试了按row1, col2, secondary_yTrue等条件挂载与update_layout_images的批量更新坐标正则xref/yref支持任意编号轴及domain后缀的语法约束直接写在自动生成的属性 docstring 中layout/_image.py。九、完整代码场景小结场景关键配置适用位置背景图layerbelow 轴坐标xrefx第二节品牌 Logoxref/yrefpaperxanchor/yanchor第三节谱图标注多图添加 update_layout_images批量统一第四节可缩放图片隐形 trace 锚点 scaleanchorsizingstretch第五节图像标注MLdragmode modebar 绘图按钮 newshape第六节子图角标xrefx domainrow/col第七节更多属性组合可参考自动生成的图表参考文档doc/python/目录下对应教程以及在仓库 plotly/graph_objs/layout/_image.py 中按属性名检索 docstring 获取完整语义说明。赞分享数据可视化数据分析【免费下载链接】plotly.pyThe interactive graphing library for Python :sparkles:项目地址https://gitcode.com/gh_mirrors/pl/plotly.py点击查看免费下载相关推荐Flot图像图表在图表中嵌入背景图片的高级应用Flot图像图表在图表中嵌入背景图片的高级应用 Flot作为一款基于jQuery的JavaScript图表库不仅能够创建精美的数据可视化图表还提供了强大的图表库数据可视化前端Granim.js图像遮罩技术为Logo添加动态渐变背景的完整指南Granim.js图像遮罩技术为Logo添加动态渐变背景的完整指南 想要为你的品牌Logo添加令人惊艳的动态渐变背景吗Granim.js这个轻量级JavaS前端终极Stirling-PDF图像添加工具指南5步精准添加水印、Logo与图章终极Stirling PDF图像添加工具指南5步精准添加水印、Logo与图章 Stirling PDF是一款功能强大的本地托管PDF处理工具提供了一站式的P后端前端桌面应用上一篇CGAL点云表面重建技术详解下一篇Oak框架测试指南如何高效测试中间件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考