geom_text_repel无法显示y=0数据点标签的解决方法咨询
问题描述
使用ggrepel::geom_text_repel绘图时,y值为0的多个数据点标签无法显示;但改用geom_text后,这些标签能正常显示。如何让geom_text_repel显示这些标签?
原始代码
df <- structure(list(country = c("Afghanistan", "Maldives", "South Korea", "Myanmar", "Hong Kong", "Nepal", "Iran", "Pakistan", "Mongolia", "Sri Lanka", "Solomon Islands", "Papua New Guinea", "Philippines", "Vanuatu", "Fiji", "India", "Thailand", "Bangladesh", "Timor-Leste", "Cambodia", "Bhutan", "Indonesia", "Malaysia", "North Korea", "China", "Laos", "Vietnam"), events_100k = c(3.98929763342097, 2.79873668427856, 2.62575870183105, 2.35641546264502, 1.82589571721442, 1.5246135146153, 0.911935371211704, 0.732282427564865, 0.732173241902643, 0.696527510433654, 0.558478859194678, 0.533576507194829, 0.437436665635902, 0.372548653981312, 0.332483712390482, 0.33108510506144, 0.287659607432814, 0.268114542694623, 0.243799197500219, 0.225647112496632, 0.214237892068302, 0.161625916810053, 0.122442381076969, 0.030958809775498, 0.0305411355867934, 0.0265856721537317, 0.0110560302970689), fatalities_100k = c(13.5403363662492, 0, 0, 2.40734372064802, 0.00103111295706451, 0.0176525607421717, 0.101916026586642, 0.281265249931412, 0.00121560201851201, 0.0427296136131635, 0.126203591830265, 0.617302833700826, 0.470032459501862, 0.0340059714485864, 0, 0.0248378913598791, 0.0649046751582995, 0.0595271434968146, 0.0176774482270748, 0.0142209364310508, 0, 0.0134710052425114, 0.00593122835659716, 0.0163140899407196, 0.000259674902575946, 0.0143455539400826, 0.00158666022175559)), row.names = c(NA, -27L), class = c("tbl_df", "tbl", "data.frame")) df |> select(-events, -fatalities) |> ggplot(aes(x = events_100k, y = fatalities_100k)) + geom_point() + geom_text(aes(label = country), vjust = "inward") + # ggrepel::geom_text_repel(aes(label = country), vjust = "inward") + scale_x_log10() + scale_y_log10()
解决方案
问题核心是对数刻度的y轴:scale_y_log10()会把y=0的数值转换为负无穷,geom_text_repel无法处理这种无效坐标,直接丢弃了对应标签;而geom_text会尝试在绘图区域底部强制显示这些标签。
提供两种可行解决方法:
方法1:给y=0的数值添加极小值
把fatalities_100k中为0的值替换成一个接近0的正数,让对数转换后得到有效坐标,geom_text_repel就能正常识别并显示标签:
library(tidyverse) library(ggrepel) df |> # 替换0为极小值1e-4,可根据需求调整 mutate(fatalities_100k = ifelse(fatalities_100k == 0, 1e-4, fatalities_100k)) |> ggplot(aes(x = events_100k, y = fatalities_100k)) + geom_point() + ggrepel::geom_text_repel(aes(label = country), vjust = "inward") + scale_x_log10() + scale_y_log10()
方法2:使用伪对数刻度
用scales::pseudo_log_trans()替代scale_y_log10(),这种刻度专门处理包含0或负数的数值,避免出现负无穷的问题:
library(tidyverse) library(ggrepel) df |> ggplot(aes(x = events_100k, y = fatalities_100k)) + geom_point() + ggrepel::geom_text_repel(aes(label = country), vjust = "inward") + scale_x_log10() + # pseudo_log_trans的sigma参数可调整0附近的刻度压缩程度 scale_y_continuous(trans = scales::pseudo_log_trans(sigma = 1e-4))
额外提示
原始代码中的select(-events, -fatalities)会报错,因为df中不存在这两列,建议删除该行。
内容的提问来源于stack exchange,提问作者Sentient_Slime_Mold
相关产品推荐
相关产品推荐

