如何设置ggplot中因子型X轴刻度、跳过间隔因子并调整ggplotly悬停显示
针对你提出的三个问题,我结合你的示例数据给出具体的解决方案:
1. 在ggplot中设置因子型X轴的刻度
当X轴是因子类型时,我们可以通过scale_x_discrete()函数灵活控制刻度的显示,包括指定要显示的刻度项(breaks)和对应的自定义标签(labels)。
比如你示例中的Year已经被转成因子,如果你想自定义显示特定年份的刻度,或者修改刻度文本,参考下面的代码:
# 示例:自定义刻度标签,将部分年份改为带"年"的格式 data %>% group_by(Year) %>% mutate(value = value / sum(value)) %>% ggplot(aes(fill=condition, y=value, x=factor(Year))) + geom_col(position="fill", width = 1, color = "white") + geom_text(aes(label = scales::percent(value, accuracy = 0.1)), position = position_fill(vjust = 0.50), color = "white") + scale_y_continuous(labels = scales::percent) + scale_fill_brewer(palette = "Set1") + # 设置X轴刻度:指定显示的因子和对应标签 scale_x_discrete(breaks = c("2015", "2017", "2018"), labels = c("2015年", "2017年", "2018年"))
如果只是想显示所有因子的刻度,直接保留默认设置即可,或者显式指定breaks = levels(factor(data$Year))来确保所有因子都被展示。
2. 设置X轴刻度并跳过每隔一个因子
要实现跳过每隔一个因子的效果,我们可以先获取因子的所有水平,再通过索引筛选出需要显示的刻度项。比如取第1、3、5...个水平,或者第2、4、6...个水平:
# 先获取Year因子的所有水平 year_levels <- levels(factor(data$Year)) # 筛选每隔一个的水平(这里取奇数位的水平:2015,2017) selected_breaks <- year_levels[seq(1, length(year_levels), 2)] data %>% group_by(Year) %>% mutate(value = value / sum(value)) %>% ggplot(aes(fill=condition, y=value, x=factor(Year))) + geom_col(position="fill", width = 1, color = "white") + geom_text(aes(label = scales::percent(value, accuracy = 0.1)), position = position_fill(vjust = 0.50), color = "white") + scale_y_continuous(labels = scales::percent) + scale_fill_brewer(palette = "Set1") + # 应用筛选后的刻度 scale_x_discrete(breaks = selected_breaks)
如果你想跳过奇数位、取偶数位的刻度,只需要把seq(1, length(year_levels), 2)改成seq(2, length(year_levels), 2)即可。
3. 将ggplotly的悬停信息从factor(Year)调整为Year
问题的根源在于你在aes(x=factor(Year))里把Year转成了因子,ggplotly识别的是因子类型的X值,所以悬停时会显示factor(Year)。这里提供两种解决方法:
方法一:提前将Year转为因子并指定顺序,在aes中直接用Year
先在数据处理阶段把Year转成因子(还可以指定顺序确保年份排列正确),这样ggplot里直接用x=Year,ggplotly就能识别原始的Year文本:
library(plotly) # 提前将Year转为因子并指定顺序(可选,确保年份按时间顺序排列) data <- data %>% mutate(Year = factor(Year, levels = c("2015", "2016", "2017", "2018"))) # 绘制ggplot图,x直接用Year p <- data %>% group_by(Year) %>% mutate(value = value / sum(value)) %>% ggplot(aes(fill=condition, y=value, x=Year)) + geom_col(position="fill", width = 1, color = "white") + geom_text(aes(label = scales::percent(value, accuracy = 0.1)), position = position_fill(vjust = 0.50), color = "white") + scale_y_continuous(labels = scales::percent) + scale_fill_brewer(palette = "Set1") # 转成ggplotly,悬停信息会显示Year而不是factor(Year) ggplotly(p)
方法二:自定义悬停文本(如果必须在aes中用factor(Year))
如果因为某些原因必须在aes里用factor(Year),可以通过添加text参数自定义悬停内容,然后在ggplotly中指定使用这个自定义文本:
library(plotly) p <- data %>% group_by(Year) %>% mutate(value = value / sum(value)) %>% ggplot(aes(fill=condition, y=value, x=factor(Year), # 自定义悬停文本,包含原始Year和其他信息 text = paste("年份:", Year, "\n", "处理:", condition, "\n", "占比:", scales::percent(value, accuracy = 0.1)))) + geom_col(position="fill", width = 1, color = "white") + geom_text(aes(label = scales::percent(value, accuracy = 0.1)), position = position_fill(vjust = 0.50), color = "white") + scale_y_continuous(labels = scales::percent) + scale_fill_brewer(palette = "Set1") # 指定tooltip使用自定义的text ggplotly(p, tooltip = "text")
内容的提问来源于stack exchange,提问作者user18948933

