在绘图图例中的标记上显示符号

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

如何更新该图中的图例,以便图例的符号位于标记上方而不是创建者之后。图例中的当前文本应替换为以下值:

c(increase = "+", decrease = "-", unknown = "?")

library(plotly)
df <- data.frame(x = 1:3, y = 0, text = c("?", "+", "-"))
plot_ly() |>
  add_trace(
    x = ~x, y = ~y, text = ~text, color = ~text, data = df,
    type = "scatter", mode = "markers+text",
    marker = list(size = 20), textfont = list(size = 12, color = "white")
  )

r plotly
1个回答
0
投票

我昨天才看到你的问题;听起来很有趣!我可以想到两种方法来实现这一点。

  1. 使用 Plotly,隐藏图例并使用
    layout.shapes
    layout.annotations
    手动重建图例。
  2. 使用
    htmlwidgets::onRender
    和 JS/JQuery。

我认为使用 Plotly-only 方法需要更多代码,所以我走上了 JS 道路。我为您提供了两种可能的解决方案。

在第一个图中,修改了绘图以将符号移动到图例图标的顶部。在第二个中,我使用了您提供的信息:增加、减少、未知,并将该信息添加到图例中并移动符号。

仅符号移动

这就是 JS 中发生的情况:

  • 捕获图例中图标/符号的 x 或水平位置
  • 对于每个图例条目
    • 克隆当前文本元素
    • 修改克隆元素:中心、x 位置、颜色
    • 将克隆的文本元素添加到图标/符号
plot_ly() |>
  add_trace(
    x = ~x, y = ~y, text = ~text, color = ~text, data = df,
    type = "scatter", mode = "markers+text",
    marker = list(size = 20), textfont = list(size = 12, color = "white")
  ) %>% 
  htmlwidgets::onRender(
    "function(el, x) {                               /* extract transform val */
      newX = $('path.scatterpts').attr('transform').match(/(?<=\\()\\d+/g)[0];
      $('text.legendtext').clone().each(function(ind) {       /* create clone */
                                              /* mod text clone & add to symb */
          cl = $(this).attr({'x': newX, 'text-anchor': 'middle'})
                      .css('fill', 'white');
          
          $('g.legendpoints')[ind].append(cl[0]); /* add new txt elem to plot */
      })
    }")

如果您想删除图标/符号右侧的文本,只需从

.clone()
中删除
$('text.legendtext').clone().each(function(ind)
(所以它是
...text').each(f...

符号移动和重新标记图例条目

首先,我将您的标签添加到数据中。

df2 <- data.frame(x = 1:3, y = 0, text = c("?", "+", "-"), 
                  symb = c("unknown", "increase", "decrease"))

在剧情中,我添加了

name = ~symb
。 在JS中,与上面唯一的区别是在克隆文本元素的修改中添加了
.text(x.data[ind].text)

plot_ly() |>
  add_trace(
    x = ~x, y = ~y, text = ~text, color = ~text, data = df2,
    type = "scatter", mode = "markers+text", name = ~symb,
    marker = list(size = 20), textfont = list(size = 12, color = "white")
  ) %>% 
  htmlwidgets::onRender(
    "function(el, x) {                               /* extract transform val */
      newX = $('path.scatterpts').attr('transform').match(/(?<=\\()\\d+/g)[0];
      $('text.legendtext').clone().each(function(ind) {       /* create clone */
                                              /* mod text clone & add to symb */
          cl = $(this).attr({'x': newX, 'text-anchor': 'middle'})
                      .css('fill', 'white')
                      .text(x.data[ind].text);           /* add symbols + - ? */
          
          $('g.legendpoints')[ind].append(cl[0]); /* add new txt elem to plot */
      })
    }")

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