在 Plotly 中跳过重叠的刻度标签 Javascript
Skip overlapping tick labels in Plotly Javascript
我们在 Plotly.JS 中使用散点图在较大的 X 范围内显示二维图形数据,因此我们使用对数缩放。缩放和平移效果很好,除了一个小问题:X 刻度标签令人困惑,因为 Plotly 使用一位数标签表示次要(非 10 的幂)刻度:
我可以使用 tickFormat: '0.1s'
来显示实数(这是用户想要的)而不是单个数字,但是在某些情况下这些标签可以重叠:
我可以也添加dtick: 'D2'
,它只显示位置 2 和 5 的子刻度,而不是所有数字,但这随后被修复并且不调整以适应缩放没有了。
理想情况下,我可以指定 subtick-label 数字在哪里完全跳过标签(但不是垂直线),而 不必求助于 tickmode: array
并且具有手动指定所有刻度标签,并且仍然受益于根据缩放比例进行的自动刻度调整。
例如,如果显示所有 subtick 数字,我会说我希望在位置 1、2、3、5、7 有刻度标签,结果将如下所示:
其他显示模式(仅数字 2 和 5,或仅 10 的幂)不会改变。
有没有办法做到这一点?如果是这样,如何?如果需要,我不怕修补 Plotly,但现在我不知道从哪里开始寻找。
通常我通过将标签旋转 35-45 度来解决这个问题。这样它们就都在那里并且仍然可读。
https://plotly.com/javascript/reference/#layout-xaxis-tickangle
tickangle
Parent: layout.xaxis
Type: angle
Default: "auto"
Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.
好的,所以我深入研究了 Plotly 配置选项,并且根据缩放级别 semi-automatically 修改了 'live' 的选项,但是条件 when 发生的那些修改是硬编码的。
所以这是一个补丁(针对 Plotly v1.36,因为这是我们目前使用的)。当从 1,10,100,... 更改为 1,2,5,10,20,50,100,... 到 1,2,3,4,5,... 标记时,我修改了一些硬编码条件对数轴并删除了最后一种情况的 4、6、8 和 9 处的刻度标签,以避免文本重叠。
对于我的应用程序,这现在运行良好,我找不到更多的刻度标签重叠。另外,我去掉了 10 的幂之间的个位数,这让一些用户感到困惑。
--- a/plotly-latest.v1.36.js 2021-05-24 21:45:28.000000000 +0100
+++ b/plotly-latest.v1.36.js 2022-02-02 10:21:08.000000000 +0100
@@ -127302,13 +127302,13 @@
if(!nt) {
if(ax.type === 'category') {
minPx = ax.tickfont ? (ax.tickfont.size || 12) * 1.2 : 15;
nt = ax._length / minPx;
}
else {
- minPx = ax._id.charAt(0) === 'y' ? 40 : 80;
+ minPx = ax._id.charAt(0) === 'y' ? 40 : 100;
nt = Lib.constrain(ax._length / minPx, 4, 9) + 1;
}
// radial axes span half their domain,
// multiply nticks value by two to get correct number of auto ticks.
if(ax._name === 'radialaxis') nt *= 2;
@@ -127395,14 +127395,21 @@
// Start with it cleared and mark that we're in calcTicks (ie calculating a
// whole string of these so we should care what the previous date head was!)
ax._prevDateHead = '';
ax._inCalcTicks = true;
var ticksOut = new Array(vals.length);
- for(var i = 0; i < vals.length; i++) ticksOut[i] = axes.tickText(ax, vals[i]);
+ // if scaling == log, skip some intermediate tick labels to avoid overlapping text
+ var skipTexts = /^[4689]/;
+ var text;
+ for(var i = 0; i < vals.length; i++) {
+ text = axes.tickText(ax, vals[i]);
+ if(ax.type == "log" && ax.dtick == "D1" && text.text.match(skipTexts)) text.text = "";
+ ticksOut[i] = text;
+ }
ax._inCalcTicks = false;
return ticksOut;
};
function arrayTicks(ax) {
@@ -127535,18 +127542,20 @@
// ticks on a linear scale, labeled fully
roughDTick = Math.abs(Math.pow(10, rng[1]) -
Math.pow(10, rng[0])) / nt;
base = getBase(10);
ax.dtick = 'L' + roundDTick(roughDTick, base, roundBase10);
+ ax.tickformat = '';
}
else {
// include intermediates between powers of 10,
// labeled with small digits
// ax.dtick = "D2" (show 2 and 5) or "D1" (show all digits)
- ax.dtick = (roughDTick > 0.3) ? 'D2' : 'D1';
+ ax.dtick = (roughDTick > 0.4) ? 'D2' : 'D1';
+ ax.tickformat = '0.1s';
+ ax.hoverformat = '0.2s'; // Workaround to fix hoverinfo label formatting
}
}
else if(ax.type === 'category') {
ax.tick0 = 0;
ax.dtick = Math.ceil(Math.max(roughDTick, 1));
}
补丁特此作为 Public 域发布,以便尽可能轻松地使用它直接集成到 Plotly 中(也许作为“D3”格式选项?)。
我们在 Plotly.JS 中使用散点图在较大的 X 范围内显示二维图形数据,因此我们使用对数缩放。缩放和平移效果很好,除了一个小问题:X 刻度标签令人困惑,因为 Plotly 使用一位数标签表示次要(非 10 的幂)刻度:
我可以使用 tickFormat: '0.1s'
来显示实数(这是用户想要的)而不是单个数字,但是在某些情况下这些标签可以重叠:
我可以也添加dtick: 'D2'
,它只显示位置 2 和 5 的子刻度,而不是所有数字,但这随后被修复并且不调整以适应缩放没有了。
理想情况下,我可以指定 subtick-label 数字在哪里完全跳过标签(但不是垂直线),而 不必求助于 tickmode: array
并且具有手动指定所有刻度标签,并且仍然受益于根据缩放比例进行的自动刻度调整。
例如,如果显示所有 subtick 数字,我会说我希望在位置 1、2、3、5、7 有刻度标签,结果将如下所示:
其他显示模式(仅数字 2 和 5,或仅 10 的幂)不会改变。 有没有办法做到这一点?如果是这样,如何?如果需要,我不怕修补 Plotly,但现在我不知道从哪里开始寻找。
通常我通过将标签旋转 35-45 度来解决这个问题。这样它们就都在那里并且仍然可读。
https://plotly.com/javascript/reference/#layout-xaxis-tickangle
tickangle
Parent: layout.xaxis
Type: angle
Default: "auto"
Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.
好的,所以我深入研究了 Plotly 配置选项,并且根据缩放级别 semi-automatically 修改了 'live' 的选项,但是条件 when 发生的那些修改是硬编码的。
所以这是一个补丁(针对 Plotly v1.36,因为这是我们目前使用的)。当从 1,10,100,... 更改为 1,2,5,10,20,50,100,... 到 1,2,3,4,5,... 标记时,我修改了一些硬编码条件对数轴并删除了最后一种情况的 4、6、8 和 9 处的刻度标签,以避免文本重叠。
对于我的应用程序,这现在运行良好,我找不到更多的刻度标签重叠。另外,我去掉了 10 的幂之间的个位数,这让一些用户感到困惑。
--- a/plotly-latest.v1.36.js 2021-05-24 21:45:28.000000000 +0100
+++ b/plotly-latest.v1.36.js 2022-02-02 10:21:08.000000000 +0100
@@ -127302,13 +127302,13 @@
if(!nt) {
if(ax.type === 'category') {
minPx = ax.tickfont ? (ax.tickfont.size || 12) * 1.2 : 15;
nt = ax._length / minPx;
}
else {
- minPx = ax._id.charAt(0) === 'y' ? 40 : 80;
+ minPx = ax._id.charAt(0) === 'y' ? 40 : 100;
nt = Lib.constrain(ax._length / minPx, 4, 9) + 1;
}
// radial axes span half their domain,
// multiply nticks value by two to get correct number of auto ticks.
if(ax._name === 'radialaxis') nt *= 2;
@@ -127395,14 +127395,21 @@
// Start with it cleared and mark that we're in calcTicks (ie calculating a
// whole string of these so we should care what the previous date head was!)
ax._prevDateHead = '';
ax._inCalcTicks = true;
var ticksOut = new Array(vals.length);
- for(var i = 0; i < vals.length; i++) ticksOut[i] = axes.tickText(ax, vals[i]);
+ // if scaling == log, skip some intermediate tick labels to avoid overlapping text
+ var skipTexts = /^[4689]/;
+ var text;
+ for(var i = 0; i < vals.length; i++) {
+ text = axes.tickText(ax, vals[i]);
+ if(ax.type == "log" && ax.dtick == "D1" && text.text.match(skipTexts)) text.text = "";
+ ticksOut[i] = text;
+ }
ax._inCalcTicks = false;
return ticksOut;
};
function arrayTicks(ax) {
@@ -127535,18 +127542,20 @@
// ticks on a linear scale, labeled fully
roughDTick = Math.abs(Math.pow(10, rng[1]) -
Math.pow(10, rng[0])) / nt;
base = getBase(10);
ax.dtick = 'L' + roundDTick(roughDTick, base, roundBase10);
+ ax.tickformat = '';
}
else {
// include intermediates between powers of 10,
// labeled with small digits
// ax.dtick = "D2" (show 2 and 5) or "D1" (show all digits)
- ax.dtick = (roughDTick > 0.3) ? 'D2' : 'D1';
+ ax.dtick = (roughDTick > 0.4) ? 'D2' : 'D1';
+ ax.tickformat = '0.1s';
+ ax.hoverformat = '0.2s'; // Workaround to fix hoverinfo label formatting
}
}
else if(ax.type === 'category') {
ax.tick0 = 0;
ax.dtick = Math.ceil(Math.max(roughDTick, 1));
}
补丁特此作为 Public 域发布,以便尽可能轻松地使用它直接集成到 Plotly 中(也许作为“D3”格式选项?)。