I have the following data frame
A <- c(2020, 2020, 2020, 2021, 2021, 2021)
B <- c("category 1", "category 2", "category 3", "category 1", "category 2", "category 3")
C <- c(7, 10, 5, 11, 8, 7)
data <- data.frame(A, B, C)
names(data) <- c("yeat", "categories", "value")
How can I plot a horizontal bar chart, that will look like this (i.e., the categories are sorted by their values for each year):
CodePudding user response:
Use barplot
in an lapply
. split
the data by year
and plot the value
s according to their order
. We also give the bars col=
ors according to this scheme as well as labels using mtext
.
Colors and labels may be conveniently stored in a matrix m
with row names by categories that we can easily match later.
(m <- matrix(c('#3C79A7', '#8ECBE9', '#FB4C58',
"Category 1", "Category 2", "Category 3"), 3, 2,
dimnames=list(sort(unique(data$categories)), NULL)))
# [,1] [,2]
# category 1 "#3C79A7" "Category 1"
# category 2 "#8ECBE9" "Category 2"
# category 3 "#FB4C58" "Category 3"
S <- split(data, data$year)
op <- par(mfrow=c(1, 2), mar=c(2, 6, 4, 2)) ## par: 2 plots, expand margins
lapply(names(S), \(x) {
s <- S[[x]]
u <- order(s$value)
barplot(s$value[u], horiz=TRUE, col=m[s$categories[u], 1], border=NA,
main=x[1], xaxt='n', yaxt='n', ylab='')
mtext(m[s$categories[u], 2], 2, 1, at=seq_len(nrow(s)), las=2)
})
par(op) ## reset pars
Data:
data <- structure(list(year = c(2020, 2020, 2020, 2021, 2021, 2021),
categories = c("category 1", "category 2", "category 3",
"category 1", "category 2", "category 3"), value = c(7, 10,
5, 11, 8, 7)), class = "data.frame", row.names = c(NA, -6L
))
CodePudding user response:
You can use this code:
library(tidyverse)
library(forcats)
library(patchwork)
A <- c(2020, 2020, 2020, 2021, 2021, 2021)
B <- c("category 1", "category 2", "category 3", "category 1", "category 2", "category 3")
C <- c(7, 10, 5, 11, 8, 7)
data <- data.frame(A, B, C)
names(data) <- c("yeat", "categories", "value")
p1 <- data %>%
filter(yeat == 2020) %>%
mutate(categories = fct_reorder(categories, value)) %>%
ggplot(aes(x = categories, y = value))
geom_col()
xlab("Categories")
ylab("")
ggtitle("2020")
coord_flip()
theme(legend.position = "none")
p2 <- data %>%
filter(yeat == 2021) %>%
mutate(categories = fct_reorder(categories, value)) %>%
ggplot(aes(x = categories, y = value))
geom_col()
xlab("Categories")
ylab("")
ggtitle("2021")
coord_flip()
theme(legend.position = "none")
p1 p2
Output:
CodePudding user response:
The definitions of the custom colors are shamelessly stolen from