如何用ggplot2调整森林图OR标签至条形上方而非中间
调整ggplot2森林图中OR标签位置至条形上方
需要修改ggplot2代码,将森林图里的OR(优势比)标签从条形中间移到条形上方,以下是原代码、当前效果及修改后的解决方案:
原代码
library(tidyverse) library(ggplot2) # Create a data frame with your odds ratios and confidence intervals odds_ratios <- c(1.290, 1.217, 1.231, 1.242) ci_lower <- c(1.107, 1.038, 1.019, 1.028) ci_upper <- c(1.504, 1.427, 1.486, 1.500) or <- c(1.29, 1.22, 1.23, 1.24) ci <- c("1.11 to 1.50", " 1.04 to 1.43", "1.02 to 1.49", "1.24 to 1.50") Model <- c("Unadjusted (AUC=53.1%)", "Adjusted for family factors (AUC=63.1%)", "Adjusted for family and self-functioning factors (AUC=85.0%)", "Adjusted for family, self-functioning, and socio-demographic factors (AUC=85.2%)") # Create a data frame data <- data.frame( Model = Model, Odds_Ratio = odds_ratios, CI_lower = ci_lower, CI_upper = ci_upper, or <- or, ci <- ci ) # Define the desired order of levels desired_order <- c("Unadjusted (AUC=53.1%)", "Adjusted for family factors (AUC=63.1%)", "Adjusted for family and self-functioning factors (AUC=85.0%)", "Adjusted for family, self-functioning, and socio-demographic factors (AUC=85.2%)") # Reorder the data frame rows based on the desired order data <- data %>% mutate(Model = factor(Model, levels = desired_order)) %>% arrange(Model) # Add a row number column data$row_num <- 1:nrow(data) # Define custom breaks and labels for the x-axis custom_breaks <- c(0.5, 1, 1.2, 1.5) custom_labels <- c(" ", "Just as likely", "1.2x as likely", "1.5x as likely") # Add significance column data$Significance <- ifelse(data$CI_lower > 1 | data$CI_upper < 1, "Significant", "Not Significant") # Wrap long labels data$Model <- factor(str_wrap(data$Model, width = 30), levels = str_wrap(desired_order, width = 30)) # Create the forest plot with customized labels ggplot(data, aes(x = Odds_Ratio, y = fct_rev(Model))) + geom_vline(xintercept = 1, linetype = "dashed", color = "gray") + geom_point(aes(x = Odds_Ratio, color = Significance), size = 3) + geom_errorbarh(aes(xmin = CI_lower, xmax = CI_upper), height = 0.3) + scale_x_continuous(breaks = custom_breaks, labels = custom_labels) + scale_color_manual(values = c("Significant" = "red", "Not Significant" = "black")) + theme_minimal() + labs(x = "Odds Ratio", y = " ") + ggtitle(paste("Odds Ratios for Family Affectedness of Individual Chronic Pain:", "\n", "Women vs. Men")) + theme( axis.title.y = element_blank(), axis.text = element_text(size = 10), panel.grid.major.y = element_line(color = "gray", linetype = "dashed"), legend.position = "none", plot.title = element_text(hjust = 0.5, lineheight = 1.2) )
当前效果

修改后的代码
library(tidyverse) library(ggplot2) # Create a data frame with your odds ratios and confidence intervals odds_ratios <- c(1.290, 1.217, 1.231, 1.242) ci_lower <- c(1.107, 1.038, 1.019, 1.028) ci_upper <- c(1.504, 1.427, 1.486, 1.500) or <- c(1.29, 1.22, 1.23, 1.24) ci <- c("1.11 to 1.50", " 1.04 to 1.43", "1.02 to 1.49", "1.24 to 1.50") Model <- c("Unadjusted (AUC=53.1%)", "Adjusted for family factors (AUC=63.1%)", "Adjusted for family and self-functioning factors (AUC=85.0%)", "Adjusted for family, self-functioning, and socio-demographic factors (AUC=85.2%)") # 修正数据框列赋值错误:将<-改为= data <- data.frame( Model = Model, Odds_Ratio = odds_ratios, CI_lower = ci_lower, CI_upper = ci_upper, or = or, ci = ci ) # Define the desired order of levels desired_order <- c("Unadjusted (AUC=53.1%)", "Adjusted for family factors (AUC=63.1%)", "Adjusted for family and self-functioning factors (AUC=85.0%)", "Adjusted for family, self-functioning, and socio-demographic factors (AUC=85.2%)") # Reorder the data frame rows based on the desired order data <- data %>% mutate(Model = factor(Model, levels = desired_order)) %>% arrange(Model) # Add a row number column data$row_num <- 1:nrow(data) # Define custom breaks and labels for the x-axis custom_breaks <- c(0.5, 1, 1.2, 1.5) custom_labels <- c(" ", "Just as likely", "1.2x as likely", "1.5x as likely") # Add significance column data$Significance <- ifelse(data$CI_lower > 1 | data$CI_upper < 1, "Significant", "Not Significant") # Wrap long labels data$Model <- factor(str_wrap(data$Model, width = 30), levels = str_wrap(desired_order, width = 30)) # Create the forest plot with OR labels above bars ggplot(data, aes(x = Odds_Ratio, y = fct_rev(Model))) + geom_vline(xintercept = 1, linetype = "dashed", color = "gray") + geom_errorbarh(aes(xmin = CI_lower, xmax = CI_upper), height = 0.3) + geom_point(aes(x = Odds_Ratio, color = Significance), size = 3) + # 添加OR标签,通过y轴偏移将标签放在条形上方 geom_text(aes(label = paste("OR =", or), y = as.numeric(fct_rev(Model)) + 0.2), size = 3, hjust = 0.5) + scale_x_continuous(breaks = custom_breaks, labels = custom_labels) + scale_color_manual(values = c("Significant" = "red", "Not Significant" = "black")) + theme_minimal() + labs(x = "Odds Ratio", y = " ") + ggtitle(paste("Odds Ratios for Family Affectedness of Individual Chronic Pain:", "\n", "Women vs. Men")) + theme( axis.title.y = element_blank(), axis.text = element_text(size = 10), panel.grid.major.y = element_line(color = "gray", linetype = "dashed"), legend.position = "none", plot.title = element_text(hjust = 0.5, lineheight = 1.2) )
关键修改点
- 修正了数据框中列的赋值错误:原代码使用
<-会导致列名异常,改为=后才能正确调用or列 - 添加
geom_text()层,通过y = as.numeric(fct_rev(Model)) + 0.2设置垂直偏移量,将OR标签放置在每个模型对应的点/误差线的上方 - 可以根据需要调整偏移数值(比如0.2)或
vjust参数来微调标签位置
内容的提问来源于stack exchange,提问作者keherder
相关产品推荐
相关产品推荐

