映射颜色时,将多列传递给绘图中的自定义数据

tho*_*hal 7 r plotly

如果我不将任何值映射到 color以下代码,则可以顺利运行:

\n
library(tidyverse)\nlibrary(plotly)\n\nset.seed(123)\nd <- tibble(x = 1:10, \n            g = gl(2, 5), \n            y = sample(100, 10), \n            L = LETTERS[1:10], l = letters[1:10])\n\nplot_ly(d) %>%\n  add_bars(x = ~ x, y = ~ y, customdata = ~ map2(l, L, list),\n           hovertemplate = "%{customdata[0]}:%{customdata[1]}")\n
Run Code Online (Sandbox Code Playgroud)\n

绘制条形图,其中悬停信息正确显示为:A

\n

然而,当我尝试为条形提供不同的颜色时,数据的(内部)形状发生变化,并且 R 抱怨形状不匹配:

\n
plot_ly(d) %>%\n  add_bars(x = ~ x, y = ~ y, color = ~ g, customdata = ~ map2(l, L, list),\n           hovertemplate = "%{customdata[0]}:%{customdata[1]}")\n
Run Code Online (Sandbox Code Playgroud)\n
\n
Error in `recycle_columns()`:\n! Tibble columns must have compatible sizes.\n\xe2\x80\xa2 Size 5: Columns `x`, `y`, `color`, `hovertemplate`, `.plotlyTraceIndex`, and\n  2 more.\n\xe2\x80\xa2 Size 10: Column `customdata`.\n\xe2\x84\xb9 Only values of size one are recycled.\nRun `rlang::last_trace()` to see where the error occurred.\n
Run Code Online (Sandbox Code Playgroud)\n
\n

显然,我的customdata形状错误,但我不知道我需要如何传递它,以便情节可以使用它?

\n

Sam*_*amR 7

我认为这可能是一个错误plotly。您的错误告诉您 columnsxyhas 是 length10customdatais length 5。但是,如果您重新调整数据的customdata长度5,例如通过提供customdata = ~ split(map2(l, L, list), 1:5),您会得到相反的错误:

\n
Error in `recycle_columns()`:\n! Tibble columns must have compatible sizes.\n\xe2\x80\xa2 Size 5: Column `customdata`.\n\xe2\x80\xa2 Size 10: Columns `x`, `y`, and `color`.\n\xe2\x84\xb9 Only values of size one are recycled.\n
Run Code Online (Sandbox Code Playgroud)\n

提供两个列表,每个列表的长度为5,例如 withcustomdata = ~ split(map2(l, L, list), g)也会产生错误。

\n

幸运的是,有一种替代方法实际上具有一些优点。我们可以创建一个函数,将每个组添加为自己的跟踪。这也意味着我们不必color直接指定(尽管可以),因为plotly每个迹线使用不同的颜色。它还会自动创建图例。

\n
add_customdata_by <- function(d, x, y, by_col, custom_col1 = l, custom_col2 = L, fn = list) {\n    d_split <- d |>\n        mutate(customdata = map2({{ custom_col1 }}, {{ custom_col2 }}, fn)) |>\n        split(d[[by_col]])\n\n    Reduce(\\(p, d) add_bars(\n        p,\n        x = ~x, y = ~y, customdata = ~ customdata,\n        hovertemplate = "%{customdata[0]}:%{customdata[1]}",\n        data = d,\n        name = unique(d$g)\n    ), d_split, init = plot_ly())\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我们可以这样调用:

\n
add_customdata_by(d, x, y, by_col = "g")\n
Run Code Online (Sandbox Code Playgroud)\n

plot_ly()在此示例中,这与调用后跟两次调用相同add_bars(),每个调用级别一次g。然而,这将推广到任意数量的组。

\n

输出

\n

在此输入图像描述

\n

我想你的主要目的customdata可能不是hoverinfo(否则你可以添加text = ~sprintf("%s:%s", l, L), hoverinfo = "text"到一个add_bars()调用中)。但是,如果您将其用于悬停文本,则此方法还具有"trace0"用组名称替换默认情况下每个标签附加的 的优点。

\n


Mat*_*t B 4

您还可以做得更简单:


library(tidyverse)
library(plotly)

set.seed(123)
d <- tibble(x = 1:10, 
            g = gl(2, 5), 
            y = sample(100, 10), 
            L = LETTERS[1:10], l = letters[1:10])

d <- tibble(x = 1:10, 
            g = gl(2, 5), 
            y = sample(100, 10), 
            L = LETTERS[1:10], l = letters[1:10])

plot_ly(d) %>%
  add_bars(x = ~ x, y = ~ y,  hovertext = ~g, marker = list(color = ~g), customdata = ~ map2(l, L, list),
           hovertemplate = "%{customdata[0]}:%{customdata[1]}(%{hovertext})<extra></extra>")

Run Code Online (Sandbox Code Playgroud)

在此输入图像描述