Here's my data:
# Data:
mydf <- data.frame(
Species = rep(c("Ungulate","Ungulate","Elk","Elk","Rodent","Rodent","Deer","Deer"),
times = 3),
Space = rep(c("W", "C", "E"), each = 8),
Age = rep(c("Adult", "Juvenile"), times = 12),
value = c(0.03,0.17,0.02,0.23,0.33,0.00,0.05,0.12,0.04,0.28,0.09,0.23,0.17,0.00,0.13,
0.17,0.02,0.14,0.01,0.23,0.29,0.00,0.06,0.13))
mydf$spaceage <- as.factor(paste(mydf$Space, mydf$Age))
mydf
myPalette <- c("#f4a582", "#b2182b", "#92c5de", "#2166ac", "#a6dba0", "#1b7837")
For my plot:
example <- ggplot(mydf,
aes(x = factor(Space, levels = c("W", "C", "E")),
y = value,
fill = factor(spaceage))) +
geom_bar(stat = 'identity', position = 'stack') +
facet_grid(~ Species) +
scale_fill_manual(values = myPalette, name = "Age") + #legend
labs(x="") +
theme_bw()
example
Is it possible to combine redundant legend items , so dark and light shades are combined, to produce something like this? (couldn't get very even sizes using paint):
I'm open to other ideas for making this legend more concise. Thanks for any advice!
You can assign ""
as legend label to some legend entries in order to achieve the effect.
However, I would first of all caution to be very careful with the manual fill scale first, as you want to make sure each colour corresponds to the correct spaceage
value before obscuring its label.
Here's an implementation:
# ensure correct mapping between colour & label
names(myPalette) <- levels(mydf$spaceage)
ggplot(mydf,
aes(x = factor(Space, levels = c("W", "C", "E")),
y = value,
fill = factor(spaceage))) +
# minor point, but geom_col() is equivalent to geom_bar(position = "identity"),
# and position = "stack" is default in both cases.
geom_col() +
facet_grid(~ Species) +
scale_fill_manual(values = myPalette, name = "Age",
# ensures colour order follows x-axis order
breaks = c("W Adult", "W Juvenile", "C Adult", "C Juvenile",
"E Adult", "E Juvenile"),
# comment out this line to verify that right colour
# is mapped to the right label
labels = c("", "", "", "", "Adult", "Juvenile"),
# specify 2 rows for legends
guide = guide_legend(nrow = 2, byrow = FALSE)) +
labs(x = "") +
theme_bw()
Create the legend, which is actually a ggplot2.
library(ggplot2)
ds_palette <- tibble::tibble(
fill = c("#a6dba0", "#1b7837", "#f4a582", "#b2182b", "#92c5de", "#2166ac"),
x = c(2, 1, 2, 1, 2, 1),
y = c(3, 3, 2, 2, 1, 1),
text = c("W", "W", "C", "C", "E", "E"),
text_color = c("black", "white", "black", "white", "black", "white")
)
legend_inset <- ggplot(ds_palette, aes(x=x, y=y, fill=fill)) +
geom_tile() +
geom_text(aes(label=text, color=text_color)) +
annotate("text", x=1, y=3.6, label="Juvenile", vjust=0) +
annotate("text", x=2, y=3.6, label="Adult", vjust=0) +
scale_color_identity() +
scale_fill_identity() +
coord_cartesian(ylim=c(0.5, 4), expand = F) +
theme_void() +
labs(x="")
Then put it all together. The objects in vpList
define the proportions of the partitioned areas.
grid.newpage()
plot_width <- .8
tree <- vpTree(
viewport(w=1, h=1, name="A"),
vpList(
viewport(x=0, y=0 , w= plot_width, h=1 , just=c("left", "bottom"), name="bar_graph"),
viewport(x=1, y=.5, w=1-plot_width, h=0.3, just=c("right", "top") , name="legend")
)
)
pushViewport(tree)
print(example , vp = "bar_graph")
print(legend_inset, vp = "legend")
I rotated your 2x3 legend so the words would be more space-efficient.
You can add labels and change the position of your legend as the code below.
example<-ggplot(mydf, aes(x = factor(Space, levels=c("W", "C", "E")), y = value, fill = factor(spaceage))) +
geom_bar(stat = 'identity', position = 'stack') + facet_grid(~ Species) +
scale_fill_manual(values = myPalette,name = "Age",labels=c("Adult","Juvenile","Adult","Juvenile","Adult","Juvenile")) + #legend
labs(x="") +
theme(legend.position = "top")
example
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.