如何在ggplotly中手动设置图例项的顺序与标签?
解决ggplotly中转译ggplot2自定义图例的问题
问题描述
我可以使用标准ggplot2创建所需的图表,代码如下:
data <- structure(list(Date = structure(c(19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266), class = "Date"), Key = c("Average Hourly Earnings", "Average Hourly Earnings", "Average Hourly Earnings", "Case Shiller House Price Index", "Case Shiller House Price Index", "Case Shiller House Price Index", "HPA", "HPA", "HPA", "Industrial Production", "Industrial Production", "Industrial Production", "Personal Consumption Expenditures", "Personal Consumption Expenditures", "Personal Consumption Expenditures", "Retail Sales", "Retail Sales", "Retail Sales", "Capacity Utilisation", "Capacity Utilisation", "Capacity Utilisation", "Total Vehicle Sales", "Total Vehicle Sales", "Total Vehicle Sales", "Construction Spending", "Construction Spending", "Construction Spending"), Value = c(-0.223065575886151, -1.40315318073944, -1.91465670559936, -2.51599837113228, NA, NA, -2.39639074829503, NA, NA, -0.620070909725157, 0.438262897380392, -1.02195804568898, -1.18062194826764, -1.04966383725284, NA, -0.434581634758551, -0.671474725212731, -0.689827602986322, 0.814973303786158, 0.792591156917412, 0.36832537554409, 2.29199981656987, 2.23432584415557, 1.83201171904481, 0.283236872921727, 0.721164674024409, NA), Color = c("#e6cc00", "#ff0000", "#ff0000", "#7b0000", NA, NA, "#7b0000", NA, NA, "#e6cc00", "#ece75f", "#ff0000", "#ff0000", "#ff0000", NA, "#e6cc00", "#e6cc00", "#e6cc00", "#ece75f", "#ece75f", "#ece75f", "#0a5d00", "#0a5d00", "#0eff00", "#ece75f", "#ece75f", NA)), row.names = c(NA, -27L), class = c("tbl_df", "tbl", "data.frame")) library(tidyverse) library(plotly) # 注:原代码中data2为笔误,应改为data p <- data %>% ggplot(aes(Date, Key, fill = Color)) + geom_tile() + theme_light() + scale_fill_identity(guide = 'legend', breaks = c('NA','#0a5d00','#0eff00', "#ece75f",'#e6cc00','#ff0000','#7b0000'), labels = c("NA",'> 2 Standard Deviations from mean', 'Between 1 and 2 Standard Deviations from mean', 'Between 0 and 1 Standard Deviations from mean', 'Between 0 and -1 Standard Deviations from mean', 'Between -1 and -2 Standard Deviations from mean', '> -2 Standard Deviations from mean')) p
这段代码通过scale_fill_identity自定义了图例的项顺序和标签,但使用ggplotly转换为交互式图表时,这些自定义设置会被忽略,转换代码如下:
p %>% ggplotly(tooltip = c('Date','Key')) %>% layout(legend = list(orientation = "h", x = 0.4, y = -0.2))
需要解决的问题:如何在ggplotly中手动设置图例项的顺序与标签,以复现ggplot2中的自定义效果?
解决方案
ggplotly对scale_fill_identity的自定义图例支持有限,我们可以通过手动修改plotly对象的跟踪(trace)属性和布局来实现需求,步骤如下:
- 定义与ggplot2完全一致的颜色-标签映射关系及顺序
- 遍历每个trace,将其名称替换为对应的自定义标签
- 重新排序trace以匹配自定义的图例顺序
- 调整布局参数确保图例显示正确
完整代码
# 加载所需包 library(tidyverse) library(plotly) # 数据定义(重复原数据确保代码独立可运行) data <- structure(list(Date = structure(c(19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266), class = "Date"), Key = c("Average Hourly Earnings", "Average Hourly Earnings", "Average Hourly Earnings", "Case Shiller House Price Index", "Case Shiller House Price Index", "Case Shiller House Price Index", "HPA", "HPA", "HPA", "Industrial Production", "Industrial Production", "Industrial Production", "Personal Consumption Expenditures", "Personal Consumption Expenditures", "Personal Consumption Expenditures", "Retail Sales", "Retail Sales", "Retail Sales", "Capacity Utilisation", "Capacity Utilisation", "Capacity Utilisation", "Total Vehicle Sales", "Total Vehicle Sales", "Total Vehicle Sales", "Construction Spending", "Construction Spending", "Construction Spending"), Value = c(-0.223065575886151, -1.40315318073944, -1.91465670559936, -2.51599837113228, NA, NA, -2.39639074829503, NA, NA, -0.620070909725157, 0.438262897380392, -1.02195804568898, -1.18062194826764, -1.04966383725284, NA, -0.434581634758551, -0.671474725212731, -0.689827602986322, 0.814973303786158, 0.792591156917412, 0.36832537554409, 2.29199981656987, 2.23432584415557, 1.83201171904481, 0.283236872921727, 0.721164674024409, NA), Color = c("#e6cc00", "#ff0000", "#ff0000", "#7b0000", NA, NA, "#7b0000", NA, NA, "#e6cc00", "#ece75f", "#ff0000", "#ff0000", "#ff0000", NA, "#e6cc00", "#e6cc00", "#e6cc00", "#ece75f", "#ece75f", "#ece75f", "#0a5d00", "#0a5d00", "#0eff00", "#ece75f", "#ece75f", NA)), row.names = c(NA, -27L), class = c("tbl_df", "tbl", "data.frame")) # 创建ggplot对象(修正原代码笔误) p <- data %>% ggplot(aes(Date, Key, fill = Color)) + geom_tile() + theme_light() + scale_fill_identity(guide = 'legend', breaks = c('NA','#0a5d00','#0eff00', "#ece75f",'#e6cc00','#ff0000','#7b0000'), labels = c("NA",'> 2 Standard Deviations from mean', 'Between 1 and 2 Standard Deviations from mean', 'Between 0 and 1 Standard Deviations from mean', 'Between 0 and -1 Standard Deviations from mean', 'Between -1 and -2 Standard Deviations from mean', '> -2 Standard Deviations from mean')) # 转换为plotly对象 p_plotly <- p %>% ggplotly(tooltip = c('Date','Key')) # 定义颜色与标签的映射(与ggplot2设置完全一致) legend_mapping <- list( 'NA' = "NA", '#0a5d00' = '> 2 Standard Deviations from mean', '#0eff00' = 'Between 1 and 2 Standard Deviations from mean', '#ece75f' = 'Between 0 and 1 Standard Deviations from mean', '#e6cc00' = 'Between 0 and -1 Standard Deviations from mean', '#ff0000' = 'Between -1 and -2 Standard Deviations from mean', '#7b0000' = '> -2 Standard Deviations from mean' ) # 获取自定义的颜色顺序 color_order <- names(legend_mapping) # 为每个trace设置正确的标签名称 for (i in seq_along(p_plotly$x$data)) { current_color <- p_plotly$x$data[[i]]$fillcolor p_plotly$x$data[[i]]$name <- legend_mapping[[current_color]] } # 重新排序trace以匹配自定义图例顺序 p_plotly$x$data <- p_plotly$x$data[match(color_order, sapply(p_plotly$x$data, function(x) x$fillcolor))] # 调整布局:设置图例方向、位置 p_plotly <- p_plotly %>% layout( legend = list( orientation = "h", x = 0.4, y = -0.2, traceorder = "normal" ) ) # 显示最终交互式图表 p_plotly
关键说明
- 修正了原代码中
data2的笔误,确保代码可正常运行 - 通过
legend_mapping统一颜色与标签的对应关系,完全对齐ggplot2的自定义设置 - 遍历修改每个trace的
name属性,确保hover提示和图例标签一致 - 使用
match函数重新排序trace,保证图例项的显示顺序与自定义要求一致 - 调整布局参数保持图例的水平显示和位置设置
内容的提问来源于stack exchange,提问作者Tanga94
相关产品推荐
相关产品推荐

