如何为R语言ggplot绘制的多系列散点图添加图例
Hey there! The problem with your current code is that you’re setting the colour parameter outside the aes() mapping for most points—ggplot can’t generate a legend when colors are hardcoded directly like that. Let’s fix this with two straightforward approaches:
Approach 1: Use Tidy Data (Recommended)
ggplot works best with "tidy" data (one observation per row). First, we’ll reshape your wide-format data into long format using tidyr::pivot_longer(), then plot with a single geom_point() call that automatically creates a legend:
library(tidyr) library(ggplot2) # Reshape data to long format tidy_resid <- residFrame %>% pivot_longer( cols = c(total_diff, desalination_diff, surfacewater_diff, groundwater_diff), names_to = "water_source", values_to = "difference" ) # Create the plot testPlot <- ggplot(tidy_resid) + geom_point(aes(x = STATEFP, y = difference, colour = water_source, shape = water_source)) + # Map water source names to your desired colors scale_colour_manual( values = c( "total_diff" = "red", "desalination_diff" = "blue", "surfacewater_diff" = "green", "groundwater_diff" = "yellow" ), # Optional: Rename legend labels to be more readable labels = c( "total_diff" = "Total", "desalination_diff" = "Desalination", "surfacewater_diff" = "Surface Water", "groundwater_diff" = "Groundwater" ) ) + # Set all points to use shape=1 scale_shape_manual(values = rep(1, 4)) + xlab('STATEFP') + ylab('Difference') + ggtitle('Difference for all states', subtitle='For each source') testPlot
This method keeps your code clean, makes it easier to update later, and aligns with ggplot’s core design principles.
Approach 2: Adjust Your Original Wide-Format Code
If you prefer not to reshape your data, you can fix the legend by moving the colour mapping inside aes() for each geom_point(), then manually define color mappings with scale_colour_manual():
library(ggplot2) testPlot <- ggplot(residFrame) + # Move colour into aes() with a label for the legend geom_point(aes(x = STATEFP, y = total_diff, colour = "Total"), shape = 1) + geom_point(aes(x = STATEFP, y = desalination_diff, colour = "Desalination"), shape = 1) + geom_point(aes(x = STATEFP, y = surfacewater_diff, colour = "Surface Water"), shape = 1) + geom_point(aes(x = STATEFP, y = groundwater_diff, colour = "Groundwater"), shape = 1) + # Map legend labels to your desired colors scale_colour_manual( values = c( "Total" = "red", "Desalination" = "blue", "Surface Water" = "green", "Groundwater" = "yellow" ) ) + xlab('STATEFP') + ylab('Difference') + ggtitle('Difference for all states', subtitle='For each source') testPlot
By putting the legend label inside aes(colour = ...), ggplot recognizes these as categories and generates a legend automatically.
内容的提问来源于stack exchange,提问作者Roelalex1996

