我正在构建一个带有多类别 x 轴的 r/plotly 图表。我找到了一种使用 rbind() 定义两个 x 轴类别的方法,但似乎找不到旋转两个类别的 x 轴刻度标签的方法(tickangle 属性仅影响第一个类别,但不影响第二个类别)。
尝试谷歌答案(当然)但找不到太多帮助。
我发现了这个讨论 - 他们提到多类别图的标签轮换是一个需要解决的问题,但目前还没有结论如何在现实中实现这一点。 https://github.com/plotly/plotly.js/issues/2799
library(plotly)
df <- data.frame(
name1 = c('Winter', 'Summer', 'Autumn', 'Winter', 'Winter', 'Summer',
'Winter', 'Autumn'),
name2 = c('VeryVeryVeryLongName_A',
'VeryVeryVeryLongName_A',
'VeryVeryVeryLongName_A',
'VeryVeryVeryLongName_B',
'VeryVeryVeryLongName_B',
'VeryVeryVeryLongName_B',
'VeryVeryVeryLongName_C',
'VeryVeryVeryLongName_C'),
Value = c('10', '11', '9', '8', '7', '6', '9', '10')
)
plot_ly(df) %>%
add_trace(x = rbind(c(~name2, ~name1)), y = ~Value, type = 'scatter', mode = 'markers') %>%
layout(xaxis = list(tickangle = 90)) #this only affects the 1st category (name1), but not the 2nd (name2).
我想找到一种方法来独立定义两个类别(name1和name2)的tickangle属性,或者找到一种方法来防止重叠第二个类别标签(长名称)。
非常感谢任何帮助。谢谢=)
修改 Plotly 调用的功能
_tickAngle(xtick =..., xtick2 = ...)
是内部设置的。目前,没有外部方法可以改变xtick2
的角度(我能找到)。
我确实想出了一个使用该包的解决方案
htmlwidgets
。这会在渲染后修改绘图,从而更改多类别 x 轴第二行的角度。
唯一的手动更改,您必须通过设置底部边距来在底部留出空间。
代码的最后一行是
}", data.frame(ang = 30)) # change to whatever angle you want
这使得更改文本角度变得非常容易。将
30
更改为您想要的任何角度。
我在代码中使用了注释来解释发生了什么。但是,如果您有任何疑问,请告诉我。
plot_ly(df) %>%
add_trace(x = rbind(c(~name2, ~name1)), y = ~Value, type = 'scatter', mode = 'markers') %>%
layout(xaxis = list(tickangle = 90), margin = list(b = 150)) %>% #<<---- I'm new!!
htmlwidgets::onRender(
"function(el, x, data) {
fixMePlease = function() {
xt2 = document.getElementsByClassName('xtick2'); /* collect elems */
[...xt2].forEach( (e, i) => { /* for each text elem */
descent = Math.abs(data[0].ang/90/2); /* space for new text position */
w = e.children[0].getBoundingClientRect().width; /* y change needed */
x = Number(e.children[0].getAttribute('x')); /* rotation x */
y = Number(e.children[0].getAttribute('y')) + descent * w; /* get old & calc new y */
trs = e.children[0].getAttribute('transform'); /* original transform to mod */
repl = ' rotate(' + data[0].ang + ',' + x + ',' + y + ')'; /* assemble transform update */
e.children[0].setAttribute('y', y); /* apply y change */
e.children[0].setAttribute('transform', trs + repl); /* apply rotation change */
});
}
el.on('plotly_afterplot', function() { /* update placement when restyling or replotting */
fixMePlease();
})
}", data.frame(ang = 30)) # change to whatever angle you want (degrees, not radians!)
这是 30、45 和 60 度时的样子(下边距分别为 150、180 和 210)。