在R语言中用子图绘制带geom点的双条形图并共用单个图例
Got it, let's tackle this problem step by step. You want two subplots (one for Petal metrics, one for Sepal metrics) that combine bar plots with scatter points, and share a single legend. Here's how to do it properly with tidyverse tools—we'll streamline your data setup first to make plotting way easier:
Step 1: Fix and Reshape Your Data
First, I’ll complete the Condition_1 assignment for df_1 (matching your existing pattern) and restructure both data frames into a long, combined format. This is critical for creating shared subplots and legends without redundant code.
library(tidyverse) # Complete your original data setup df_1 <- iris[,c("Species", "Petal.Length","Petal.Width")] df_2 <- iris[,c("Species", "Sepal.Length","Sepal.Width")] df_1["Condition_1"] <- "P condition" df_1[10:20,"Condition_1"] <- "Q condition" df_1[20:30,"Condition_1"] <- "R condition" df_1[30:40,"Condition_1"] <- "S condition" df_1[40:50,"Condition_1"] <- "T condition" df_1[60:70,"Condition_1"] <- "Q condition" df_1[70:80,"Condition_1"] <- "R condition" df_1[80:90,"Condition_1"] <- "S condition" df_1[90:100,"Condition_1"] <- "T condition" df_1[110:120,"Condition_1"] <- "Q condition" df_1[120:130,"Condition_1"] <- "R condition" df_1[130:140,"Condition_1"] <- "S condition" df_1[140:150,"Condition_1"] <- "T condition" # Add a label to distinguish Petal vs Sepal metrics df_1 <- df_1 %>% mutate(Metric_Type = "Petal") df_2 <- df_2 %>% mutate(Metric_Type = "Sepal") # Reshape to long format (so we can plot all measurements in one go) df_1_long <- df_1 %>% pivot_longer(cols = c(Petal.Length, Petal.Width), names_to = "Measurement", values_to = "Value") df_2_long <- df_2 %>% pivot_longer(cols = c(Sepal.Length, Sepal.Width), names_to = "Measurement", values_to = "Value") # Combine into one master data frame, and carry over Condition_1 to df_2 combined_df <- bind_rows(df_1_long, df_2_long) combined_df$Condition_1 <- rep(df_1$Condition_1, 2) # Matches condition mapping across both datasets
Step 2: Create the Faceted Plot with Bars + Points
Now we’ll use ggplot2 to build the subplots, overlay raw data points on summary bars, and set up a single shared legend.
ggplot(combined_df, aes(x = Species, y = Value, fill = Condition_1)) + # Bar plot: Show mean values with error bars (adjust if you want counts instead) stat_summary(fun = mean, geom = "bar", position = position_dodge(width = 0.8), width = 0.7) + stat_summary(fun.data = mean_se, geom = "errorbar", position = position_dodge(width = 0.8), width = 0.2) + # Overlay raw data points, jittered to avoid overlap and aligned with bars geom_point(aes(color = Condition_1), position = position_jitterdodge(jitter.width = 0.2, dodge.width = 0.8), alpha = 0.6) + # Split into subplots for Petal vs Sepal, with flexible y-axes facet_wrap(~Metric_Type, scales = "free_y") + # Merge fill/color legends into one shared legend scale_fill_discrete(name = "Experimental Condition") + scale_color_discrete(name = "Experimental Condition") + # Clean up the theme for readability theme_bw() + theme( legend.position = "bottom", # Place shared legend at the bottom axis.text.x = element_text(angle = 45, hjust = 1) ) + labs( x = "Iris Species", y = "Measurement Value" )
Key Notes:
- Data Reshaping: By combining your two data frames into a single long-format dataset, we use
facet_wrapto create subplots automatically—this ensures the legend is shared because the grouping variable (Condition_1) is consistent across all data. - Bars + Points:
stat_summarycreates summary bars (here, mean values) which pair well with raw data points.position_dodgeandposition_jitterdodgekeep bars and points aligned by condition. - Shared Legend: Mapping both bar fill and point color to
Condition_1, then giving both scales the same name, merges them into one unified legend. Adjustlegend.positionto place it wherever works best for your plot.
If you wanted bars to show counts instead of summary stats, replace the stat_summary lines with geom_bar(stat = "count", position = position_dodge)—just note that raw points might make less sense with count bars.
内容的提问来源于stack exchange,提问作者prateekeshwar singh

