Data:
df <- structure(list(interval = c("1990-1994", "1995-1999", "2000-2004",
"2005-2009", "2010-2014"), G = c(82.2047540759008, 66.8830947511929,
60.8452885555918, 60.815015015015, 56.9713761985336), I = c(0.0816584033395321,
0.0878634449241925, 0.0880830474237161, 0.0808069481620484, 0.0871282403928035
)), row.names = c(NA, -5L), class = "data.frame")
Code:
library(ggplot2)
library(ggrepel)
#Set label text size
ts=6
#Define theme
pt <- theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_blank(),
panel.background=element_blank(), panel.border=element_rect(fill=NA, colour="black"),
axis.line=element_line(colour="black"), axis.title=element_blank(), axis.ticks = element_blank(),
axis.text=element_blank(), aspect.ratio=1)
#Generate plot
ggplot(df, aes(x=I, y=G/100, label=interval)) + geom_point() +
geom_text_repel(aes(label=interval), size=ts, direction="both", min.segment.length=Inf, nudge_x=.06, hjust=0) +
scale_x_continuous(limits=c(-1,1), breaks=c(-1,0,1), labels=c("", 0, ""), expand=c(0,0)) +
scale_y_continuous(limits=c(0,1), breaks=c(0,.5,1), expand=c(0,0)) +
geom_hline(yintercept=0.5) + geom_vline(xintercept=0) +
annotate("text", size=ts, x=0.02, y=0.03, label="0", hjust=0) +
annotate("text", size=ts, x=0.97, y=0.03, label="I", hjust=1, fontface="italic") +
annotate("text", size=ts, x=0.02, y=0.47, label="0.5", hjust=0) +
annotate("text", size=ts, x=0.02, y=0.97, label="G", hjust=0, fontface="italic") + pt
Result:
The default placement of the labels by ggrepel results in a messy look even though the points are quite regularly aligned vertically, so I've tried to arrange the labels in more orderly fashion on the right hand-side. The points labelled "2005-2009" and "2000-2004" overlap almost completely so I've set direction="both" in geom_text_repel to avoid overcrowding labels on the right hand-side. I've also set min.segment.length=Inf because drawing segments adds unnecessary clutter for only 5 data points. I wish to align "2005-2009" horizontally with its data point, but tweaking nudge_x, hjust and vjust values fails to do that.
For these data, geom_text_repel might be overkill. You can achieve similar spacing with geom_label. Only the "2005-2009" data point needs a different horizontal alignment from the rest, which can be be accomplished through the hjust parameter:
ggplot(df, aes(x=I, y=G/100, label=interval)) + geom_point() +
geom_label(aes(label=interval, hjust = ifelse(interval == '2005-2009', 1, 0)), size=ts, label.padding = unit(0.3, "lines"), fill = NA, label.size = NA) +
scale_x_continuous(limits=c(-1,1), breaks=c(-1,0,1), labels=c("", 0, ""), expand=c(0,0)) +
scale_y_continuous(limits=c(0,1), breaks=c(0,.5,1), expand=c(0,0)) +
geom_hline(yintercept=0.5) + geom_vline(xintercept=0) +
annotate("text", size=ts, x=0.02, y=0.03, label="0", hjust=0) +
annotate("text", size=ts, x=0.97, y=0.03, label="I", hjust=1, fontface="italic") +
annotate("text", size=ts, x=0.02, y=0.47, label="0.5", hjust=0) +
annotate("text", size=ts, x=0.02, y=0.97, label="G", hjust=0, fontface="italic") + pt
Related
I use an #| layout-ncol option in quarto to place figures side-by-side. However, in combination with the chunk option fig.width the font size is changing as well. It seems as if the plot is zoomed in. I am searching for quite some time for a solution but was not able to figure out how to maintain all font sizes at a fixed size. I produced a little example illustrating the problem:
Only difference between first and second chunk is basically the addition of fig.width=3 in the second chunk.
---
format:
html:
theme: default
---
```{r echo=FALSE, message=FALSE, warning=FALSE, fig.asp=1}
#| layout-ncol: 2
library(ggplot2)
data <- data.frame(
x = c(1:10),
y = c(11:20)
)
ggplot(data=data, aes(x=x, y=y)) +
geom_smooth(method = 'lm') + geom_point() + theme_classic() +
theme(axis.title = element_text(
size = 10)) +
ylab("Y-Axis") +
xlab("X-Axis")
ggplot(data=data, aes(x=x, y=y)) +
geom_smooth(method = 'lm') + geom_point() + theme_classic() +
theme(axis.title = element_text(
size = 10)) +
ylab("Y-Axis") +
xlab("X-Axis")
```
```{r echo=FALSE, message=FALSE, warning=FALSE, fig.asp=1, fig.width=3}
#| layout-ncol: 2
ggplot(data=data, aes(x=x, y=y)) +
geom_smooth(method = 'lm') + geom_point() + theme_classic() +
theme(axis.title = element_text(
size = 10)) +
ylab("Y-Axis") +
xlab("X-Axis")
ggplot(data=data, aes(x=x, y=y)) +
geom_smooth(method = 'lm') + geom_point() + theme_classic() +
theme(axis.title = element_text(
size = 10)) +
ylab("Y-Axis") +
xlab("X-Axis")
```
Would be happy for any help!
Ok, I finally just found the answer myself. When using #| layout-ncol and no fig.width is defined for that chunk, the ggplot seems to be rescaled in a way that results in smaller font sizes of the plots text elements. So the solution is just to always define a fig.width that fits the respective columns where ggplots are displayed. I think there is a clear explenation for that, but I don't it. :D
I want to pull away these overlapping labels in ggplot.
I am seeking for help to pull away each label to avoid overlapping. I've tried modify box.padding, max.overlaps, min.segment.length but still faild.
data = read.csv("995_matched_cancer_types.csv", header=T)
names(data) <- c("cancer_types","primary_disease","cell_lines")
data <- subset(data, data$primary_disease!="Unknown")
data["counts"] <- data$cell_lines/sum(data$cell_lines)
data["info"] <- paste0(data$cancer_types,"(",data$cell_lines,")")
ggplot(data, aes(x=1, y=counts, label=info, fill=cancer_types)) +
geom_bar(stat="identity", position = position_dodge2(), color="black") +
geom_text_repel(position=position_dodge2(.9),
box.padding = .5,
max.overlaps = 30,
min.segment.length = 0,
ylim = c(.03,Inf)) +
labs(x = NULL, y = NULL, fill = NULL)+
theme_classic() + theme(axis.line.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
strip.text = element_text(size = 12),
legend.position = "none"
)+
facet_wrap(~primary_disease)
If someone would help me with this problem, I would really appreciate it.
I have changed ylim = c(.03,Inf) to ylim = c(NA,Inf). This removes most of the overlaps. You can play around with the xlim and ylim values (in my opinion). You can try different height and width parameters of the ggsave function as well.
ggplot(data, aes(x=1, y=counts, label=info, fill=cancer_types)) +
geom_bar(stat="identity", position = position_dodge2(), color="black") +
geom_text_repel(position=position_dodge2(.9),
box.padding = 0.5,
max.overlaps = 30,
min.segment.length = 0,
ylim = c(NA,Inf)) +
labs(x = NULL, y = NULL, fill = NULL)+
theme_classic() + theme(axis.line.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
strip.text = element_text(size = 12),
legend.position = "none"
)+
facet_wrap(~primary_disease)
# save plot as png
ggsave("fig.png",
width = 20,
height = 10,
units = "in"
)
I am trying to add p-values to my boxplots but I keep get this error:
Error in is.factor(x) : object 'group' not found
p_vals<- tibble::tribble(
~group1, ~group2, ~p, ~y.position,
"Sync", "Meta", 0.0420994, 35,
"Sync", "Poly", 0.2497937, 30,
"Meta", "Poly", 0.5471125, 30)
and this is my ggplot command
ggplot(CD4, aes(x=group,y=data,group=group, fill=as.factor(group), outlier.colour="red")) + stat_boxplot(geom ='errorbar', width = 0.2) +
geom_boxplot(alpha = 0.75,outlier.shape = NA, show.legend = FALSE) +
geom_point(aes(fill=group),pch=21,size=2,colour="black",position = "jitter", show.legend = FALSE, alpha = 10)+
ggtitle("CD4_naive") +
labs(x = "Group",y="% of CD4+ T cells") +
theme_classic() +
theme(legend.position = "none") +
scale_y_continuous(labels = percent_format(accuracy = 1))+
scale_fill_manual(values = c("#29ada0", "#f7bb25", "#E71D36"))+
theme_prism(base_size = 9) +
add_pvalue(p_vals)
The only problem is with the last line in the command, could you please help me? is it related to the tibble or the names?
Someone knows how to delete axis.title.y from a gg.gap() plot?
I'm trying using theme () but it doesn't work...
For example using a gg.gap() package example:
I did a ggplot without any y and x axis titles ("p" plot), but when I used "p" in gg.gap to create a gap in y axis, the axis titles appears again...
data(mtcars)
library(ggplot2)
p<-ggplot(data = mtcars, aes(x = gear, fill = gear)) +geom_bar() +ggtitle("Number of Cars by Gear") +xlab("Gears") +
theme( axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.x = element_blank(),
axis.text.x = element_blank())
pgg <- gg.gap(plot=p,segments=c(5,10),tick_width = c(1,10),ylim=c(0,50))
And neither theme() works...
pgg + theme( axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.x = element_blank(),
axis.text.x = element_blank())
Thank you in advance!
This one is interesting. As #teunbrand mentioned, you should be able to fix this via scale_y_continuous(name=""), or my preference: name=NULL. It doesn't work though in any permutation!
What seems to work is setting the axis title to NULL or "" using lab(y=...) or ylab(). I thought this worked wherever you added it, but seems that you need to add to the plot before applying the gg.gap() function:
# this doesn't work
p <- p + scale_y_continuous(NULL)
pgg <- gg.gap(plot=p,segments=c(5,10),tick_width = c(1,10),ylim=c(0,50))
pgg
# this doesn't work either
pgg + scale_y_continuous(NULL)
# this apparently won't work
pgg <- gg.gap(plot=p,segments=c(5,10),tick_width = c(1,10),ylim=c(0,50))
pgg + ylab(NULL)
# this works
p <- p + ylab(NULL)
pgg <- gg.gap(plot=p,segments=c(5,10),tick_width = c(1,10),ylim=c(0,50))
pgg
I have a ggplot of countries (X axis) over two different time periods (Y axis), so double bar for each country.
I would like to see the values of each bar. I used geom_text but I get the values on the same line so they are not in place. How can I use geom_text for this type of plot ?
Rcountry %>%
gather("Type", "Value",-Country) %>%
ggplot(aes(Country, Value, fill = Type)) +
geom_bar(position = "dodge", stat = "identity") +
coord_flip()+
theme_minimal()+scale_fill_grey()+
theme(legend.position="bottom")+
theme(legend.title = element_blank())+
scale_fill_manual(values=c("darkslategray4", "darkslategrey"))+
labs(x="Country", y="Stock of robots per thousands worker in '000")+
geom_text(aes(label=c(X2010, X2018)), size=3.5)```
Thank you
This can be achieved by adding position = position_dodge(.9) to geom_text, i.e. you have to the positioning used in geom_bar to geom_text to get the labels right. Using mtcars as example data, try this:
library(ggplot2)
library(dplyr)
mtcars2 <- mtcars %>%
group_by(cyl, gear) %>%
summarise(mpg = mean(mpg)) %>%
ungroup()
ggplot(mtcars2, aes(x = factor(cyl), mpg, fill = factor(gear))) +
geom_bar(position = "dodge", stat = "identity") +
theme_minimal() +
scale_fill_grey() +
theme(legend.position="bottom")+
theme(legend.title = element_blank())+
labs(x="Country", y="Stock of robots per thousands worker in '000")+
geom_text(aes(label = mpg), position = position_dodge(.9), size=3.5) +
coord_flip()
Created on 2020-04-15 by the reprex package (v0.3.0)