I was able to use patchwork to align two xaxis, but when I add ggbreak::scale_break(), it no longer aligns. What am I doing wrong here? Code of alignment issues follows. UnComment out scale_break() lines to see difference.
library(scales)
library(ggplot2)
library(ggbreak)
library(patchwork)
y <- as_tibble(c(rnorm(400,100,25),250) )
n= nrow(y)
cor = n/100
a.mean = mean(y$value)
a.median= quantile(y$value,0.5)
a.sd = sd(y$value)
binwidth = 5
upper.limit <- 260
plt1 <-ggplot(y, aes(x="", y = value) ) +
geom_boxplot(fill = "lightblue", color = "black", outlier.shape=NA) +
stat_boxplot(geom='errorbar',coef=NULL) +
stat_summary(fun=mean, geom="point", shape=23, size=7.6, color="black", fill = "blue") +
coord_flip() +
theme_classic() +
theme(panel.border = element_rect(color="black", fill = NA, size = 1),
axis.text = element_text(size=14)) +
xlab("") +
ylab("Value ($)") +
#scale_y_break(c(200,240 ) ) +
scale_y_continuous(breaks=pretty(c(0,upper.limit), n=10), limits=c(0,upper.limit) ) +
theme(axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
axis.text.x.top=element_blank(),
axis.ticks.x.top=element_blank() )
plt2 <- ggplot(y, aes(x = value) ) +
geom_histogram(aes(y = (..count..)/sum(..count..)*100 ),
position = "identity", binwidth = 5,
fill = "lightblue", color = "black") +
stat_function(fun = function(x)
dnorm(x, mean = a.mean, sd = a.sd) * n * binwidth / cor,
color="darkblue", size =1) +
ylab("Percentage") +
xlab("") +
#scale_x_break(c(200,240 ) ) +
scale_x_continuous(breaks=pretty(c(0,upper.limit), n=10), limits=c(0,upper.limit) ) +
scale_y_continuous(breaks=seq(0,15, by=2.5)) +
theme(panel.border = element_rect(color="black", fill = NA, size = 1),
plot.title = element_text(hjust = 0.5),
text=element_text(size=20),
axis.text = element_text(size=14),
axis.text.x.top=element_blank(),
axis.ticks.x.top=element_blank() )
Fig01_01 <- plt2 / plt1 + plot_layout(nrow = 2, heights = c(10, 2) )
Fig01_01
One solution might be to manually/invisibly add in the y-axis labels and ticks for the bottom plot as exactly the same size as the upper plot. ggbreak does additionally seem to add in an immovable margin around the whole plotting area, so you may have some extra white space between plots doing it this way:
library(scales)
library(tidyverse)
library(ggbreak)
library(patchwork)
y <- as_tibble(c(rnorm(400,100,25),250) )
n= nrow(y)
cor = n/100
a.mean = mean(y$value)
a.median= quantile(y$value,0.5)
a.sd = sd(y$value)
binwidth = 5
upper.limit <- 260
plt1 <-ggplot(y, aes(x=1, y = value) ) +
geom_boxplot(fill = "lightblue", color = "black", outlier.shape=NA) +
stat_boxplot(geom='errorbar',coef=NULL) +
stat_summary(fun=mean, geom="point", shape=23, size=7.6, color="black", fill = "blue") +
coord_flip() +
theme_classic() +
theme(panel.border = element_rect(color="black", fill = NA, size = 1),
axis.text = element_text(size=14)) +
xlab(" ") +
ylab("Value ($)") +
scale_y_break(c(200,240 ) ) +
scale_y_continuous(breaks=pretty(c(0,upper.limit), n=10), limits=c(0,upper.limit) ) +
theme(axis.text.y=element_text(colour = "white", size = 14),
axis.ticks.y=element_line(colour = "white"),
axis.text.x.top=element_blank(),
axis.title.y=element_text(size=20),
axis.ticks.x.top=element_blank() )
plt2 <- ggplot(y, aes(x = value) ) +
geom_histogram(aes(y = (..count..)/sum(..count..)*100 ),
position = "identity", binwidth = 5,
fill = "lightblue", color = "black") +
stat_function(fun = function(x)
dnorm(x, mean = a.mean, sd = a.sd) * n * binwidth / cor,
color="darkblue", size =1) +
ylab("Percentage") +
xlab("") +
scale_x_break(c(200,240 ) ) +
scale_x_continuous(breaks=pretty(c(0,upper.limit), n=10), limits=c(0,upper.limit) ) +
scale_y_continuous(breaks=seq(0,15, by=2.5)) +
theme(panel.border = element_rect(color="black", fill = NA, size = 1),
plot.title = element_text(hjust = 0.5),
text=element_text(size=20),
axis.text = element_text(size=14),
axis.text.x.top=element_blank(),
axis.ticks.x.top=element_blank() )
Fig01_01 <- plt2 / plt1 + plot_layout(nrow = 2, heights = c(6, 2) )
Fig01_01
Related
How can I transform this bar plot into a pie chart?
This is the bar plot I have:
This is the code I use to make the bar plot:
dados_gráfico_distrito <- dados_desde_2015 %>%
filter(!is.na(qsd_distrito_nascimento_rec)) %>%
group_by(anoletivo_cat) %>%
count(anoletivo_cat, qsd_distrito_nascimento_rec) %>%
mutate(pct = n / sum(n), pct_label = scales::percent(pct, accuracy=1))
dados_gráfico_distrito$qsd_distrito_nascimento_rec <- factor(dados_gráfico_distrito$qsd_distrito_nascimento_rec, levels = c("Other", "Porto", "Braga"))
ggplot(dados_gráfico_distrito, aes(x= anoletivo_cat, fill = qsd_distrito_nascimento_rec, y = pct)) +
geom_bar(position = "fill", stat="identity", width = 0.5) +
geom_text(aes(label = paste(pct_label), y = pct), position = position_fill(vjust = 0.5), colour = "black", size = 3.2) +
scale_y_continuous(labels = scales::percent) +
labs(y = " ", x = " ", fill=" ") +
theme_void() + scale_fill_brewer(palette="Paired") +
theme(legend.text = element_text(size = 8, colour = "black")) +
theme(axis.text = element_text(size = 8, colour = "black")) +
theme(legend.position = "bottom", legend.direction = "horizontal") +
guides(fill = guide_legend(reverse=TRUE)) +
theme(plot.margin = unit(c(1, 1, 1, 1), "cm")) +
theme(panel.grid = element_line(colour="grey90")) +
theme(panel.grid.minor.y = element_line(color = "white"), panel.grid.major.x = element_line(color = "white"))
When I try to transform it in a pie chart, adding the code line coord_polar () I get this chart:
This is what I pretend:
Thank you!
As you did not provide sample data, I have used some other sample data. Perhaps this will meet your needs. Please modify as necessary.
library(ggrepel)
library (ggplot2)
df = read.csv("https://www.dropbox.com/s/lc3xyuvjjkyeacv/inputpie.csv?dl=1")
df <- df %>% group_by(fac) %>%
mutate(
facc = ifelse(fac=="f1", "15/16 to 19/20", "20/21"),
cs = rev(cumsum(rev(per))),
text_yp = per/2 + lead(cs, 1),
text_yp = if_else(is.na(text_yp), per/2, text_yp)
) %>% data.frame()
df$type <- factor(df$type, levels=unique(df$type))
ggplot(df, aes(x="", y=per, fill=type )) +
geom_bar(stat="identity", width=1) +
coord_polar("y", start=0) +
facet_grid(facc~. ) +
scale_fill_brewer(palette="Paired") +
theme_void() +
geom_label_repel(
aes(label = text_y, y = text_yp), show.legend = FALSE
) +
scale_y_continuous(labels = scales::percent) +
labs(y = " ", x = " ", fill=" ") +
theme(legend.text = element_text(size = 8, colour = "black")) +
#theme(axis.text = element_text(size = 8, colour = "black")) +
#theme(legend.position = "bottom", legend.direction = "horizontal") +
guides(fill = guide_legend(reverse=TRUE)) +
theme(plot.margin = unit(c(1, 1, 1, 1), "cm")) +
theme(panel.grid = element_line(colour="grey90")) +
theme(panel.grid.minor.y = element_line(color = "white"), panel.grid.major.x = element_line(color = "white"))
I want to change the text size of my y axis descrption and center my plottitle.
Everything coded within the themes function is not being applied to my graph.
Where is the problem?
finalchart = ggplot(euall,
aes(day, cumulative_cases_of_14_days_per_100000 ,
group = countriesAndTerritories)) +
geom_bar(stat = "identity" ,
col = "white" ,
fill = "darkred") +
facet_wrap("countriesAndTerritories") +
geom_line(aes(y = rollmean(cumulative_cases_of_14_days_per_100000, 1,
na.pad = TRUE),
col = "pink"),
show.legend = FALSE) +
labs(title = "COVID infections in the European Union in September 2020" ,
x = "\nSeptember" ,
y = "Infections per 100'000\n" ,
caption = "source: https://opendata.ecdc.europa.eu/covid19/casedistribution/csv") +
theme(axis.text.y = element_text(size = 5) ,
axis.title.y = element_text(size = 10) ,
plot.title = element_text(hjust = 0.5)) +
theme_minimal()
finalchart
The problem is the order in which you call theme() and theme_minimal(). By calling theme_minimal() second your manual settings in theme() are overwritten.
library(ggplot2)
library(patchwork)
p1 <- ggplot(data = cars, aes(x = speed, y = dist)) +
geom_point() +
ggtitle("theme_minimal second") +
theme(title = element_text(size = 24, color = "red", face = "bold")) +
theme_minimal()
p2 <- ggplot(data = cars, aes(x = speed, y = dist)) +
geom_point() +
ggtitle("theme_minimal first") +
theme_minimal() +
theme(title = element_text(size = 24, color = "red", face = "bold"))
p1+p2
I was trying to create a layout with plots sharing the same legend. The legend is on the top of the first plot, however, the next plot has a different scale. How can I solve this?
library(ggplot2)
library(gridExtra)
grid.arrange(
ggplot(mpg, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top")
,
ggplot(mpg, aes(displ, cty)) +
geom_point(shape = 1) +
stat_smooth(method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
)
If the plots also have the same axes labels, facet_wrap may be a good option.
library(ggplot2)
data = rbind(data.frame("id" = 1, mpg), data.frame("id" = 2, mpg))
ggplot(data, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
facet_wrap(~id, ncol = 1 ) +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top",
strip.background = element_blank(),
strip.text.x = element_blank()) #these two lines remove the facet strips
grid.arrange doesn't try to align plot panels; it's a generic function meant for all kinds of grid graphics, and in this case since the top plot has a legend it gets shrunk to fit in the available space (by default 1/2 of the page here). For the specific case of ggplots I would use egg::ggarrange,
library(ggplot2)
library(egg)
ggarrange(
ggplot(mpg, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top")
,
ggplot(mpg, aes(displ, cty)) +
geom_point(shape = 1) +
stat_smooth(method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
)
I don't know how to use grid.arrange, but here's a solution using my cowplot package. The idea is to separate the legend out from the plot and then put the three elements into one column. A similar approach would work with grid.arrange, I assume.
library(cowplot)
p1 <- ggplot(mpg, aes(displ, cty)) +
geom_point(aes(shape = "Data")) +
stat_smooth(aes(linetype = "Regression"), method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
scale_shape_manual(values = 1) +
labs(shape = "", linetype = "") +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
legend.position = "top")
p2 <- ggplot(mpg, aes(displ, cty)) +
geom_point(shape = 1) +
stat_smooth(method = "lm",
formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
theme_classic() +
theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
legend <- get_legend(p1)
plot_grid(legend, p1 + theme(legend.position = "none"), p2,
ncol=1, rel_heights = c(0.1, 1, 1))
I have the plot below and I would like the facet plot labels to be what is in "lbl" =
> lbl
[1] "0% - 10%" "10% - 20%"
How can labeller be added to the facet_wrap to get that text to show up and how does labeller correctly handle the ordering of that is output from the labeller function? i.e. If I have 20 plots how does labeller correctly label the plots in the right order? Thank you.
here is the code:
x = c( rep(c(1,2,3,4,5),4) )
group = c( rep(c(10,10,10,10,10),2),rep(c(20,20,20,20,20),2) )
lbl = paste0( c("0%", paste0( unique(group)[1:(length(unique(group))-1)] ,"%" ) )
," - ",
paste0(unique(group),"%"))
lbl
value = rnorm(20)
dat = data.frame( x= x , group = group, value = value)
dat = dat %>% # create the mu, sd, q1 and q3 aggregates
group_by(group,x) %>%
summarise(mu = round(mean(value),2),
sd= sqrt(round(sd(value),2)),
Q1 = quantile(value)[2],
Q3 = quantile(value)[4],
count = n())
dat
dat2 = dat %>% gather (key = Metric, value= Value,c(mu, sd, Q1, Q3)) #melt the data
as.data.frame(dat2)
ggplot(data=dat2 , aes(x=x, y=Value, group = Metric,colour = Metric,linetype = Metric)) +
geom_line() + geom_point() + ylab("value") +
xlab("v") +
scale_x_discrete(breaks = c( seq(1,5,1) ) ) +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
scale_y_continuous(breaks = c( seq(-3,3,.25) ) ) +
scale_colour_manual(values=c(mu = "blue", sd = "blue", Q1 = "red", Q3 = "red")) +
scale_linetype_manual(values =c(mu = "dashed", sd= "solid", Q1 = "solid", Q3 = "solid")) +
facet_wrap(~ group, scales = "free",ncol=3) +
theme(strip.text.x = element_text(size=10, angle=0),
strip.text.y = element_text(size=12, face="bold"),
strip.background = element_rect(colour="red", fill="#CCCCFF"))
You just need to build a labeller; read ?labeller and here, ?as_labeller for help. All you really need to add is labeller = as_labeller(setNames(lbl, sort(unique(group)))) (or a suitably named vector, constructed how you like) to facet_wrap:
ggplot(data=dat2 , aes(x=x, y=Value, group = Metric,colour = Metric,linetype = Metric)) +
geom_line() + geom_point() + ylab("value") +
xlab("v") +
scale_x_discrete(breaks = c( seq(1,5,1) ) ) +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
scale_y_continuous(breaks = c( seq(-3,3,.25) ) ) +
scale_colour_manual(values=c(mu = "blue", sd = "blue", Q1 = "red", Q3 = "red")) +
scale_linetype_manual(values =c(mu = "dashed", sd= "solid", Q1 = "solid", Q3 = "solid")) +
facet_wrap(~ group, scales = "free",ncol=3,
# add a labeller here:
labeller = as_labeller(setNames(lbl, sort(unique(group))))) +
theme(strip.text.x = element_text(size=10, angle=0),
strip.text.y = element_text(size=12, face="bold"),
strip.background = element_rect(colour="red", fill="#CCCCFF"))
Just trying to fix this overlapped labeling:
My code:
values=c(164241,179670)
labels=c("Private", "Public")
colors=c("#cccccc", "#aaaaaa")
categoriesName="Access"
percent_str <- paste(round(graph$values / sum(graph$values) * 100,1), "%", sep="")
values <- data.frame(val = graph$values, Type = graph$labels, percent=percent_str )
pie <- ggplot(values, aes(x = "", y = val, fill = Type)) + geom_bar(width = 1) +
geom_text(aes(y = **val + 1**, **hjust=0.5**, **vjust=-0.5**, label = percent), colour="#333333", face="bold", size=10) +
coord_polar(theta = "y") + ylab(NULL) + xlab(NULL) +
scale_fill_manual(values = graph$colors) + labs(fill = graph$categoriesName) +
opts( title = graph$title,
axis.text.x = NULL,
plot.margin = unit(c(0,0,0,0), "lines"),
plot.title = theme_text(face="bold", size=14),
panel.background = theme_rect(fill = "white", colour = NA) )
print(pie)
Tried messing with the values marked with asterisks (** **) but haven't got anywhere.
Any help appreciated.
here is an example:
pie <- ggplot(values, aes(x = "", y = val, fill = Type)) +
geom_bar(width = 1) +
geom_text(aes(y = val/2 + c(0, cumsum(val)[-length(val)]), label = percent), size=10)
pie + coord_polar(theta = "y")
Perhaps this will help you understand how it work:
pie + coord_polar(theta = "y") +
geom_text(aes(y = seq(1, sum(values$val), length = 10), label = letters[1:10]))