如何避免ggplot2中图例按字母顺序自动重排序?
Got it, let's sort out that legend order issue! The problem here is that when you use add_rownames(), the resulting rowname column is treated as a plain character vector. By default, ggplot sorts character-based legends alphabetically—so that's why your original order is getting lost.
The fix is simple: convert rowname to a factor with levels explicitly set to match the original row order of your qw dataframe. This tells ggplot exactly which order to use for the legend.
Here's your modified code with the fix included:
qw %>% add_rownames() %>% # Lock in original row order by converting to a factor mutate(rowname = factor(rowname, levels = rownames(qw))) %>% gather(reading, value, -rowname) %>% group_by(rowname) %>% mutate(x = 1:n()) %>% ggplot(aes(x = x, y = value, group = rowname)) + geom_line(aes(color = rowname), linewidth = 2.5) + # Note: `line` is deprecated, use linewidth instead geom_point(size = 1.05) + # `cex` is deprecated, use size for consistency labs(colour = "Methods", x = "XXXX", y = "YYYY") + theme( axis.text = element_text(size = 14), axis.title = element_text(size = 14), legend.text = element_text(size = 12) ) + scale_x_continuous(breaks = 1:10, limits = c(1, 10)) # Combined xlim and scale for cleaner code
Quick Breakdown of the Fix:
- The
mutate(rowname = factor(rowname, levels = rownames(qw)))line is the key. It takes the original row names fromqwand sets them as the fixed levels for therownamefactor. ggplot will respect this order for both the legend and color mapping. - I also updated a couple of deprecated ggplot arguments (
line→linewidth,cex→size) to avoid warnings in newer versions of ggplot2—this is optional but keeps your code up to date. - Combined
xlim()andscale_x_continuous()into one call since you're already defining breaks here, making the code a bit cleaner.
This should make your legend display in the exact order of rows as they appeared in your original qw dataframe, no more alphabetical sorting!
内容的提问来源于stack exchange,提问作者Ester Silva

