简体   繁体   中英

Set the legend of a ggplotly() plot to have only the color and not the shape index

I have the dataframe below:

etf_id<-c("a","b","c","d","e","a","b","c","d","e","a","b","c","d","e")
factor<-c("A","A","A","A","A","B","B","B","B","B","C","C","C","C","C")
normalized<-c(-0.048436801,2.850578601,1.551666490,0.928625186,-0.638111793,
              -0.540615895,-0.501691539,-1.099239823,-0.040736139,-0.192048665,
              0.198915407,-0.092525810,0.214317734,0.550478998,0.024613778)
df<-data.frame(etf_id,factor,normalized)

and I create a ggplotly() boxplot with:

library(ggplot2)
library(plotly)
ggplotly(ggplot(data = df, aes(x = factor, y = normalized)) +
                   geom_boxplot(aes(fill = as.factor(factor)),outlier.colour = 'black') +
                   geom_point(data = df, position = position_dodge(0.75))+geom_point(data = df, 
                                                                                    aes(x = factor, y = normalized, shape = etf_id, color = etf_id), 
                                                                                     size = 2))

I take as a result a boxplot with this legend: 在此处输入图片说明 but I want my legend to have only the color distinction like below. Note that the factors wont be 3 every time but may vary from 1 to 8.

One quick way would be to add show.legend = FALSE to supress the legend from showing.

library(ggplot2)

ggplot(data = df, aes(x = factor, y = normalized)) +
  geom_boxplot(aes(fill = as.factor(factor)),outlier.colour = 'black') +
  geom_point(position = position_dodge(0.75)) + 
  geom_point(aes(x = factor, y = normalized, shape = etf_id, color = etf_id), 
              size = 2, show.legend=FALSE)

在此处输入图片说明

Unfortunately, this does not work when this is passed to ggplotly . You can use theme(legend.position='none') which works but suppresses all the legends instead of specific ones. One dirty hack is to disable specific legend manually

temp_plot <- ggplotly(ggplot(data = df, aes(x = factor, y = normalized)) +
  geom_boxplot(aes(fill = as.factor(factor)),outlier.colour = 'black') +
  geom_point(position = position_dodge(0.75)) + 
  geom_point(aes(x = factor, y = normalized, shape = etf_id, color = etf_id),size = 2))

temp_plot[[1]][[1]][4:9] <- lapply(temp_plot[[1]][[1]][4:9], function(x) {x$showlegend <- FALSE;x})

temp_plot

在此处输入图片说明

The recommended way to alter plotly elements is to use the style() function. You can identify the elements and traces by inspecting plotly_json() .

I'm not sure if there's a more compact way, but you can achieve the desired result using:

p <- ggplotly(ggplot(data = df, aes(x = factor, y = normalized)) +
           geom_boxplot(aes(fill = as.factor(factor)),outlier.colour = 'black') +
           geom_point(data = df, position = position_dodge(0.75))+geom_point(data = df, 
                                                                             aes(x = factor, y = normalized, shape = etf_id, color = etf_id), 
                                                                             size = 2))

p <- style(p, showlegend = FALSE, traces = 5:9)
for (i in seq_along(levels(df$factor))) {
  p <- style(p, name = levels(df$factor)[i], traces = i)
}

p

Note that in this case the factor levels and traces align but that won't always be the case so you may need to adjust this (ie i + x).

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM