为ggplot中两种颜色设置独立的透明度(alpha)刻度
I've created a scatter plot where rectangles have transparency that changes with values. Here's my code:
ggplot(data = df_ch1,aes(IMPORTANCE, PERFORMANCE)) + geom_point(aes(size = N), alpha = 0.2) + facet_wrap(~Attitude, labeller = label_wrap_gen(30))+ theme_light()+ labs(fill = "Classification")+ theme(axis.text.x = element_text(angle=45, hjust = 1), strip.text = element_text(size = 12, face = "bold"))+ scale_size(range = c(5,10))+ geom_text(aes(x = 1.5, y = 1.5,label = label4))+ geom_text(aes(x = 3.5, y = 3.5,label = label1))+ geom_text(aes(x = 3.5, y = 1.5,label = label2))+ geom_text(aes(x = 1.5, y = 3.5,label = label3))+ scale_x_discrete(labels = c("Very unimportant", "Somewhat unimportant", "Somewhat important", "Very Important"))+ #geom_rect(aes(xmin = 2.55, xmax = 4.45, ymin= 0.55, ymax = 2.45,alpha = rect_color_dw1), fill = "darkred")+ scale_alpha(range = c(0, 0.1), breaks = (c(0, 0.2, 0.4, 0.6, 0.8, 1)), labels = percent(c(0, 0.2, 0.4, 0.6, 0.8, 1)/2)) + geom_rect(data = df_ch1, aes(xmin = 2.55, xmax = 4.45, ymin= 2.55, ymax = 4.45, alpha = rect_color_up1), fill = 'darkgreen', inherit.aes = T) + labs(alpha = "Percentage")
The plot works fine when the red rectangle line is commented out. But when I uncomment that line to add the second red rectangle, the legend turns grayscale, which feels counterintuitive. I want to set separate transparency scales with corresponding colors for the red and green rectangles—Is this possible?
ggnewscale for Multiple Alpha Legends Absolutely doable! The catch here is that ggplot2 only lets you have one legend per aesthetic (like alpha) out of the box. To get separate transparency legends tied to each rectangle’s color, you’ll want to use the ggnewscale package—it’s made exactly for adding multiple scales for the same aesthetic across different layers.
Here’s how to tweak your code to make this work:
- First, install and load the package if you haven’t already:
install.packages("ggnewscale") library(ggnewscale)
- Rework your plot code to split the rectangle layers with
new_scale("alpha"):
ggplot(data = df_ch1,aes(IMPORTANCE, PERFORMANCE)) + geom_point(aes(size = N), alpha = 0.2) + facet_wrap(~Attitude, labeller = label_wrap_gen(30))+ theme_light()+ labs(fill = "Classification")+ theme(axis.text.x = element_text(angle=45, hjust = 1), strip.text = element_text(size = 12, face = "bold"))+ scale_size(range = c(5,10))+ geom_text(aes(x = 1.5, y = 1.5,label = label4))+ geom_text(aes(x = 3.5, y = 3.5,label = label1))+ geom_text(aes(x = 3.5, y = 1.5,label = label2))+ geom_text(aes(x = 1.5, y = 3.5,label = label3))+ scale_x_discrete(labels = c("Very unimportant", "Somewhat unimportant", "Somewhat important", "Very Important"))+ # First: Add the red rectangle and its alpha scale geom_rect(aes(xmin = 2.55, xmax = 4.45, ymin= 0.55, ymax = 2.45, alpha = rect_color_dw1), fill = "darkred")+ scale_alpha(range = c(0, 0.1), breaks = c(0, 0.2, 0.4, 0.6, 0.8, 1), labels = scales::percent(c(0, 0.2, 0.4, 0.6, 0.8, 1)/2), name = "Red Rectangle %") + # Label the legend clearly # Reset the alpha aesthetic for the next layer new_scale("alpha") + # Now add the green rectangle and its own alpha scale geom_rect(data = df_ch1, aes(xmin = 2.55, xmax = 4.45, ymin= 2.55, ymax = 4.45, alpha = rect_color_up1), fill = 'darkgreen', inherit.aes = T) + scale_alpha(range = c(0, 0.1), breaks = c(0, 0.2, 0.4, 0.6, 0.8, 1), labels = scales::percent(c(0, 0.2, 0.4, 0.6, 0.8, 1)/2), name = "Green Rectangle %") + # Unique label for this legend labs(size = "N") # Optional: Clean up the size legend label
Quick Explanations:
new_scale("alpha")is the magic here—it tells ggplot to "reset" the alpha aesthetic, so the next layer’s alpha mapping doesn’t overwrite the first one.- By giving each
scale_alphaa uniquename, you’ll have two distinct legends, each with swatches matching their rectangle’s color (red for the first, green for the second) instead of a generic grayscale one. - Make sure the
scalespackage is loaded (it’s usually included with ggplot2, but if you get an error, just runlibrary(scales)).
This setup will give you exactly what you want: separate transparency scales, each tied to their rectangle’s color, making the plot much more intuitive to read.
内容的提问来源于stack exchange,提问作者Tomasz Wojtas

