R 绘制独立的函数图例

mat*_*mat 6 r ggplot2 plotly ggplotly r-plotly

我想通过 R 绘制具有独立图例的图,同时尊重色阶。

这就是我所拥有的:

library(plotly)

X <- data.frame(xcoord = 1:6,
                ycoord = 1:6,
                score  = 1:6,
                gender = c("M", "M", "M", "F", "F", "F"),
                age = c("young", "old", "old", "old", "young", "young"))

plot_ly(data = X, x = ~xcoord, y = ~ycoord, split = ~interaction(age, gender),
        type = "scatter", mode = "markers",
        marker = list(color = ~score,
                      colorbar = list(len = .5, y = .3)))
Run Code Online (Sandbox Code Playgroud)

这是结果:
结果

正如您所看到的,颜色条混乱,两个类别纠缠在一起。

我需要为age(年轻与年老)和gender(男与女)分别提供图例,可以彼此独立地单击。这将是预期的结果:
预期结果


编辑 1
这相当于ggplot2

gg <- ggplot(X, aes(x = xcoord, y = ycoord)) +
  geom_point(aes(color = score, shape = gender, alpha = age), size = 5) +
  scale_shape_manual(values = c("M" = 19, "F" = 19)) +
  scale_alpha_manual(values = c("young" = 1, "old" = 1))

ggplotly(gg)
Run Code Online (Sandbox Code Playgroud)

它确实在 ggplot 中正确显示,但在应用ggplotly().

请注意,我更喜欢使用原生plotly绘图的解决方案,而不是其他帖子中提出的事后修复。 ggplotly()


编辑2
虽然当前的答案确实解开了两个图例(agegender),但它们不起作用。例如,如果您单击关卡young,整个age图例将打开/关闭。这里的目标是每个图例的每个子级别都可以独立于其他级别进行切换,并且通过单击图例的级别,点将相应地显示/隐藏。

pho*_*lzm 4

Plotly 似乎不容易支持这一点,因为不同的指南链接到多个跟踪。因此,取消选择“年龄”轨迹上的“旧”不会从“性别”轨迹的单独点集中删除任何内容。

crosstalk这是使用数据对象的解决方法SharedData。这不是(取消)选择绘图轨迹,而是在绘图使用的数据集上使用过滤器。它在技术上实现了所请求的选择行为,但它是否是一个可行的解决方案取决于最终的应用程序。如果该机制适合您,可能有多种方法可以调整样式和布局,使其更具情节性。

library(crosstalk)

#SharedData object used for filters and plot
shared <- SharedData$new(X) 

crosstalk::bscols(
  widths = c(2, 10),
   list(
     crosstalk::filter_checkbox("Age", 
                                label = "Age",
                                sharedData = shared, 
                                group = ~age),
     crosstalk::filter_checkbox("Gender", 
                                label = "Gender",
                                sharedData = shared, 
                                group = ~gender)
   ),
   plot_ly(data = shared, x = ~xcoord, y = ~ycoord,
           type = "scatter", mode = "markers",
           marker = list(color = ~score,
                         colorbar = list(len = .5, y = .3),
                         cmin = 0, cmax = 6)) %>%
    layout(
      xaxis = list(range=c(.5,6.5)),
      yaxis = list(range=c(.5,6.5))
    )
   )
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

编辑:将所有复选框初始化为“已选中”

我只能通过修改输出 HTML 标签来做到这一点。这会产生相同的图,但在一开始就选中了所有框。

out <- crosstalk::bscols(...) #previous output object

library(htmltools)
out_tags <- htmltools::renderTags(out)

#check all Age and Gender checkboxes
out_tags$html <- stringr::str_replace_all(
  out_tags$html, 
  '(<input type="checkbox" name="(Age|Gender)" value=".*")/>',
  '\\1 checked="checked"/>'
)
out_tags$html <- HTML(out_tags$html)
# view in RStudio Viewer
browsable(as.tags(out_tags))
#or from Rmd chunk
as.tags(out_tags)
Run Code Online (Sandbox Code Playgroud)