You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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_wrap to create subplots automatically—this ensures the legend is shared because the grouping variable (Condition_1) is consistent across all data.
  • Bars + Points: stat_summary creates summary bars (here, mean values) which pair well with raw data points. position_dodge and position_jitterdodge keep 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. Adjust legend.position to 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:52:15