There's probably some library that does this floating around but you can just make it with ggplot2
and ggrepel
.
Some example data.
df <- structure(list(position = c(0.76, 1.199, 0.352, 0.631, 0.55,
1.332, 1.195, 1.033, 1.115, 1.097, 1.91, 1.456, 1.003, 1.653,
1.211, 1.666, 1.506, 1.705, 1.544, 1.682), pvalue = c(1.30102999566398,
2, 0.698970004336019, 1.52287874528034, 1.39794000867204, 3,
1.69897000433602, 1.22184874961636, 3, 1.30102999566398, 1.39794000867204,
1.52287874528034, 1.69897000433602, 2, 3, 1.30102999566398, 1.52287874528034,
1.39794000867204, 1.30102999566398, 1.22184874961636), term = c("Term1",
"Term2", "Term3", "Term4", "Term5", "Term6", "Term7", "Term8",
"Term9", "Term10", "Term11", "Term12", "Term13", "Term14", "Term15",
"Term16", "Term17", "Term18", "Term19", "Term20"), log2fc = c(0.17,
-1.48, 1.27, -1.23, 0.5, 1.67, -1.63, 0.62, -2.01, 0.91, -0.32,
0.3, -1.15, 0.48, 2.11, -0.95, 1.34, -1.21, 0.7, 1.49)), class = "data.frame", row.names = c(NA,
-20L))
The ggplot2 code.
library("ggplot2")
library("ggrepel")
library("dplyr")
df |>
mutate(
deg_status=case_when(
log2fc > 1 & pvalue > -log10(0.05) ~ "Up",
log2fc < -1 & pvalue > -log10(0.05) ~ "Down",
TRUE ~ "n.s."
)
) |>
ggplot(aes(x=pvalue, y=position)) +
geom_segment(
aes(x=0, xend=pvalue, y=position, yend=position),
color=rgb(0.75, 0.75, 0.75)
) +
geom_point(aes(size=abs(log2fc), color=deg_status)) +
geom_vline(xintercept=0, size=0.5) +
geom_point(aes(x=0, y=position)) +
geom_text_repel(
aes(x=0, y=position, label=term, color=deg_status),
xlim=c(Inf, -Inf), direction="y", nudge_x=0.25, size=3, segment.size=0.2,
hjust=0, show.legend=FALSE
) +
scale_x_reverse() +
coord_cartesian(clip="off") +
scale_color_manual(values=c("Down"="red", "Up"="green", "n.s."="dimgrey")) +
theme_classic() +
theme(
legend.position="bottom",
plot.margin=unit(c(0.25, 2, 0.25, 0.25), "cm"),
panel.grid.major=element_line(color=rgb(0.9, 0.9, 0.9), linewidth=0.25)
) +
guides(color=guide_legend(ncol=1), size=guide_legend(ncol=1)) +
labs(
x=bquote(-log[10](italic(P)*"-value")), y="Position (Mbp)",
color="DEG\nStatus", size=bquote(abs(log[2](Fold ~ Change)))
)
Would highly recommend adding
coord_flip()
to this plot.This would break the
geom_text_repel
part of the code, so you would need to do a bit more editing on that and a few other lines. Just to keep it clean and proper though it's better at that point to just flip the x and y references where they appear in the code.Amazing! Thank you for your innovation.