如何在Plotly.js三元图中随画布尺寸动态调整注释位置?
问题描述
我用Python版Plotly制作的三元散点图,注释能随画布尺寸变化自动调整相对位置,布局始终一致。但改用Plotly.js重构后,调整画布宽高(比如从700改为800)时,注释的相对位置发生偏移,甚至出现内容截断的情况。尝试调整yref参数但未解决问题,附上简化实现代码,求问如何让注释随画布尺寸变化自动保持相对位置?
简化代码
JavaScript代码
// 定义自动生成三元轴的函数 function makeAxis(title, tickangle, gridcolor) { return { "title": title, "titlefont": { "size": 20 }, "tickangle": tickangle, "tickfont": { "size": 15 }, "tickcolor": '#FFFFFF', "ticklen": 8, "min": 0, "showline": true, "showgrid": true, "ticks": 'outside', "tickmode": 'array', "tickvals": [0,10,20,30,40,50,60,70,80,90,100], "gridcolor": gridcolor, "gridwidth": 1.8, "tickcolor": gridcolor, "tickwidth": 1.8, }; } // 获取绘图容器元素 const ternary_plot_div = document.getElementById('ternary_soil') // 设置基础绘图数据 const ternaryBaseData = [{ // 空的基础散点图 "a": [], "b": [], "c": [], "type": 'scatterternary', }, // 绘制Sandy Clay分类的轮廓与填充 { "a": [0.55, 0.35, 0.35, 0.55], "b": [0.45, 0.65, 0.45, 0.45], "c": [0.00, 0.00, 0.20, 0.00], "type": 'scatterternary', "mode": 'lines', "line": { "width":3, "color":'black' }, "showlegend": false, "fill": 'toself', "fillcolor": 'rgba(1.0, 0.7, 0.7, 0.2)', "hoverinfo": 'none' } ]; // 设置三元图布局 const figH = 700; const figW = 700; const text_bg_color = 'rgba(0,0,0,0.4)' const annotation_text_color = '#fff' const layout = { // 基础外观配置 "autosize": false, "width": figW, "height": figH, // 三元轴配置 "ternary": { "sum": 100, "aaxis": makeAxis('', 0, 'rgba(0, 230, 230, 0.8)'), "baxis": makeAxis('', 45, 'rgba(230, 0, 230,0.8)'), "caxis": makeAxis('', -45, 'rgba(230, 191, 0, 0.8)') }, // 注释配置:标题、轴标签、区域标签 "annotations": [ // 图标题 { "showarrow": false, "text": 'USDA土壤/沉积物<br>质地分类', "x": 0.5, "y": 1.2, "xref": "paper", "yref": "paper", "font": { "size": 25 } }, // Sand轴标签 { "text":"<b>砂粒 (%)</b>", "showarrow": false, "x": 0.5, "y": -0.15, "xref": "paper", "yref": "paper", "font": { "size": 26, "color": '#000' }, "align": 'center' }, // Clay轴标签 { "text":"<b>黏粒 (%)</b>", "showarrow": false, "x": 0.015, "y": 0.555, "xref": "paper", "yref": "paper", "font": { "size": 26, "color": '#000' }, "align": 'center', "textangle": -60 }, // Silt轴标签 { "text":"<b>粉粒 (%)</b>", "showarrow": false, "x": 0.965, "y": 0.575, "xref": "paper", "yref": "paper", "font": { "size": 26, "color": '#000' }, "align": 'center', "textangle": 60 }, // Sandy Clay区域标签 { "text": '<b>砂质<br>黏粒</b>', "showarrow": false, "xref": "ternary", "yref": "ternary", "a": 0.45, // 对应三元坐标的a值,取区域中心 "b": 0.55, // 对应三元坐标的b值 "c": 0.10, // 对应三元坐标的c值 "font": { "size": 17, "color": annotation_text_color, }, "align": 'center', "bordercolor": '#000', "borderwidth": 2, "borderpad": 2, "bgcolor": text_bg_color, "hovertext": '砂质黏粒土壤组成:<br>黏粒: 35-55%<br>粉粒: 0-20%<br>砂粒: 45-65%' } ]}; // 绘制图表 Plotly.newPlot(ternary_plot_div, ternaryBaseData, layout);
HTML代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 引入Plotly.js --> <script src="https://cdn.plot.ly/plotly-2.18.2.min.js"></script> <title>土壤三元图</title> </head> <body> <br><br><br> <div id='ternary_soil'><!-- Plotly图表将绘制在此DIV内 --></div> </body> <!-- 引入三元图脚本 --> <script src='./throw_away_ternary.js'></script> </html>
解决核心要点
- 移除错误的注释属性:原代码中给注释添加了
"type": 'scatterternary',这是数据系列(trace)的类型,不属于注释配置,会干扰注释的定位逻辑,必须删除。 - 正确设置坐标系参考:
- 全局注释(标题、轴标签):设置
xref: "paper"和yref: "paper",使用0-1的比例值定位,这样注释会相对于整个画布的比例保持位置,缩放画布时不会偏移。 - 三元图内部的区域标签:设置
xref: "ternary"和yref: "ternary",并使用a/b/c属性绑定三元坐标(取值对应三元图的比例,总和为1),这样标签会始终固定在三元图的对应区域中心,不受画布尺寸变化影响。
- 全局注释(标题、轴标签):设置
- 避免内容截断:确保注释的
bgcolor和borderpad设置合理,同时如果开启autosize: true,Plotly会自动调整布局适配容器,也可以通过监听容器尺寸变化,调用Plotly.relayout()动态更新宽高。
内容的提问来源于stack exchange,提问作者eigenVector5
相关产品推荐
相关产品推荐

