如何在绘图中旋转多类别x轴刻度标签?

问题描述 投票:0回答:1

我正在构建一个带有多类别 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属性,或者找到一种方法来防止重叠第二个类别标签(长名称)。

非常感谢任何帮助。谢谢=)

r plotly
1个回答
0
投票

修改 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)。

30 degree45 degree

60 degree

© www.soinside.com 2019 - 2024. All rights reserved.