I am using the ggpubr package to do boxplots with ggboxplot. Any suggestions on how to increase the distance between the adjacent boxplots?
I have been using R for a couple of weeks and I am aware that my script might be written better.
My code:
flowdata <- read.csv("flowdata.csv", header = TRUE, sep = ";")
flowdata$Haplotype = factor(flowdata$Haplotype,levels(flowdata$Haplotype)
[c(5,1,2,3,4,6)])
library(ggpubr)
p<-ggboxplot(flowdata, x="TP", y="Treg", add = "jitter",width = 0.5, shape
= "Treatment", fill = "Haplotype", palette = c("#0092d1","#62b232","#b23a32","#b232a3","#99cccc","#132a64"))+scale_shape_manual(values = c(21,23))
p1<-p+theme(legend.title = element_blank(), legend.text = element_text(size=8), text = element_text(family = "Calibri"), axis.text.x = element_text(angle = 45, hjust = 1))+ labs(x = expression(paste("")),
y = expression(paste(CD4^+{}, CD25^+{}, "cells/µL")))
p1
The parameter 'width' specifies the width of the boxes, so a simple solution would be to reduce that value (from 0.5). This would not increase spacing of the boxes, but increase spacing between them and therefore make the boxes narrower.
However, it seems to me like your boxplots are well spaced, but your points (jitter) are overlapping, making the graph look messy. A simpler solution would be to remove them, or change them to points instead of jitter. Alternatively you could use a violin plot.
For finer control, 'standard' ggplot2 can be used, perhaps with cowplot which can give you formatting:
p <- ggplot(data = flowdata, mapping = aes(x = TP, y = Treg, fill = Haplotype)) +
geom_boxplot(position = position_dodge(0.5)) +
geom_jitter(aes(shape = Treatment)) +
scale_shape_manual(c(21, 23)) +
scale_fill_manual(c("#0092d1","#62b232","#b23a32","#b232a3","#99cccc","#132a64")) +
theme(legend.title = element_blank(), legend.text = element_text(size=8), text = element_text(family = "Calibri"), axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(x = expression(paste("")), y = expression(paste(CD4^+{}, CD25^+{}, "cells/µL")))
Building on Adams answer, I would furthermore suggest you get the boxplots into several facets, so that the plot is actually readable. I suppose the haplotype might be the interesting facet. Also, you could reduce the size of the jitter points or get some transparency alpha so that they are less present, but with the facet the boxplots are larger already, so this might solve the problem of readability by itself.
p <- ggplot(flowdata, aes(x = TP, y = Treg)) +
geom_boxplot(position = position_dodge(0.5)) +
geom_jitter(aes(shape = Treatment), size = 0.5, alpha = 0.8) +
facet_wrap(~Haplotype, ncol = 3) +
scale_shape_manual(c(21, 23)) +
theme(legend.title = element_blank(),
legend.text = element_text(size=8),
text = element_text(family = "Calibri"),
axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(x = "",
y = expression(paste(CD4^+{}, CD25^+{}, "cells/µL")))
Related
I would like to plot the congruence effects (incongruent minus congruent) as a violin plot per combination of stimulus age and response type. This is what my code looks like so far. I am not yet satisfied with the representation. How can I change it so that for each of the four conditions (adult frown, adult smile, child frown, child smile) I get the corresponding violin plot horizontally next to each other? Thanks in advance for the help. Attached is the code and an excerpt from the data frame.
violin plot
dataset$congruency_effect <- ifelse(dataset$congruency == "congruent", dataset$avgAmplitude, -dataset$avgAmplitude)
p <- ggplot(dataset, aes(x = stimulusResponse, y = congruency_effect, fill = congruency_effect, group = stimulusAge)) +
geom_violin() +
geom_point(position = position_dodge(width = 0.75), size = 3, stat = "summary", fun.y = "mean") +
scale_fill_manual(values = c("#F8766D", "#00BFC4")) +
ggtitle("Conventional EEG 350-450 ms") +
scale_y_continuous(limits = c(-5, 5)) +
facet_wrap(~stimulusAge, scales = "free_x")
EEG_Conventional450_age_response <- p + theme(
# Set the plot title and axis labels to APA style
plot.title = element_text(face = "bold", size = 16),
axis.title = element_text(face = "bold", size = 14),
# Set the axis tick labels to APA style
axis.text = element_text(size = 12),
# Set the legend title and labels to APA style
legend.title = element_text(face = "bold", size = 14),
legend.text = element_text(size = 12),
# Set the plot and panel backgrounds to white
panel.background = element_rect(fill = "white"),
plot.background = element_rect(fill = "white")
)
EEG_Conventional450_age_response
excerpt data frame
several permutations of arguments in ggplot
This has to do with the grouping aesthetic. Remove it, and your plot works.
library(ggplot2)
set.seed(42)
dataset <- data.frame(stimulusResponse = rep(c("frown", "smile"), each = 20),
congruency_effect = rnorm(40),
stimulusAge = rep(c("baby", "adult"), 20))
## removed group = stimulusAge
ggplot(dataset, aes(x = stimulusResponse, y = congruency_effect)) +
geom_violin() +
geom_point(position = position_dodge(width = 0.75), size = 3, stat = "summary") +
facet_wrap(~stimulusAge, scales = "free_x")
I don't know how to align the dots to each belong to it is box plot.
Why they are appearing like that?
I found this post, but it is answering the dodging part which is not part of my code
here is my code
library(phyloseq)
library(ggplot2)
plot_richness(ps.prev.intesParts.f, x = "part", measures = "Shannon",
color = "Samples") +
geom_boxplot() +
theme_classic() +
theme(text = element_text(size = 20),
strip.background = element_blank(),
axis.text.x.bottom = element_text(angle = 90),
legend.title = element_blank())) +
labs(x = "Intestinal Parts", y = "Shannon Index")
Could you please advise?
You are correct that you need to specify dodging. However, dodging needs to be set in the underlying geom_point(...) of the plot_richness function itself. Unfortunately, phyloseq offers no such option. This means you'll need to calculate the alpha diversity measures yourself and generate your own plot. Luckily this only requires a few extra lines of code. Here's an example using phyloseq's GlobalPatterns.
require("phyloseq")
require("dplyr")
require("ggplot2")
# Load data
data("GlobalPatterns")
# Calculate alpha indices
a_div <- estimate_richness(GlobalPatterns, measures = "Shannon")
a_div$SampleID <- row.names(a_div)
# Add sample_data from physeq object
a_div <- left_join(a_div,
sample_data(GlobalPatterns),
by = c("SampleID" = "X.SampleID"))
# GlobalPatterns only has grouping by SampleType.
# Generate an extra group by duplicating all rows
a_div <- rbind(a_div, a_div)
a_div$Samples <- rep(x = c("MMV", "VMV"),
each = nrow(a_div)/2)
# Plot
ggplot(a_div,
aes(x = SampleType,
y = Shannon,
colour = Samples)) +
geom_boxplot(position = position_dodge(width = 0.9)) +
geom_point(position = position_dodge(width = 0.9)) +
theme_classic() +
theme(text = element_text(size = 20),
strip.background = element_blank(),
axis.text.x.bottom = element_text(angle = 90,
hjust = 1,
vjust = 0.5),
legend.title = element_blank())
Created on 2022-09-02 by the reprex package (v2.0.1)
How to place the numbers centralized and in their correct positions? I have tested numerous parameters but I have not found a solution. Everything was very confusing after coordin_flip (). Observe the image and code below.
Code:
# Package
library(ggplot2)
# Create a dataframe
RATE <- c('IgG','IgG','IgA/IgG','IgA/IgG')
GROUP <- c('Asymptomatic','Symptomatic','Asymptomatic','Symptomatic')
N_POSITIVE <- c(12,100,14,107)
PORCENT <- c(7.05, 58.8, 7.73, 59.1)
df <- data.frame(RATE, GROUP, N_POSITIVE, PORCENT)
# Plot
ggplot(df, aes(x = RATE, y = PORCENT, fill = GROUP)) +
geom_bar(stat="identity", width = 0.5) +
geom_text(aes(label=N_POSITIVE),
vjust = -0.3, color = 'black',
size = 3) +
coord_flip() +
labs(x = '', y = 'Percentage (%)\n') +
scale_fill_manual(values = c("#0073c2", "#efc000")) +
theme_classic() +
theme(
legend.position = "top",
legend.title = element_blank(),
axis.text = element_text(angle = 0, color = "black", size = 10, face = 0),
axis.title.x = element_text(angle = 0, color = "black", size = 12, face = 0))
Image:
Does this do what you want? (minus the other formatting which I left out)
ggplot(df, aes(x = PORCENT, y = RATE, fill = GROUP)) +
geom_col(width = 0.5) +
geom_text(aes(label=N_POSITIVE),
vjust = -0.3, color = 'black', hjust = 1.1,
size = 3, position = "stack")
(Note, since ggplot2 3.3.0 in March 2020, most geom's don't need coord_flip if you assign them to the axis you want. If it doesn't interpret correctly, there's also an "orientation" parameter but that doesn't seem necessary here. Also, geom_col is equal to geom_bar(stat="identity").)
I am using R and ggplot2 to do some plots for publishing purposes. I have come across this plot and I would like to replicate it using ggplot2. However, I have never seen a plot like this made using ggplot2.
Can it be done with ggplot2? What about the text below the bars? I guess these will have to be hard coded in the ggplot2 codes. And how do you align those text?
This gets fairly close:
# Generate sample data (I'm too lazy to type out the full labels)
df <- data.frame(
perc = c(60, 36, 44, 41, 42, 57, 34, 52),
type = rep(c("blue", "green"), 4),
label = rep(c(
"Individual reports created as needed",
"Regular reports on single topics",
"Analytics using data integrated from multiple systems",
"Business unit-specific dashboards and visuals"), each = 2))
library(ggplot2)
ggplot(df, aes(1, perc, fill = type)) +
geom_col(position = "dodge2") +
scale_fill_manual(values = c("turquoise4", "forestgreen"), guide = FALSE) +
facet_wrap(~ label, ncol = 1, strip.position = "bottom") +
geom_text(
aes(y = 1, label = sprintf("%i%%", perc)),
colour = "white",
position = position_dodge(width = .9),
hjust = 0,
fontface = "bold") +
coord_flip(expand = F) +
theme_minimal() +
theme(
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
strip.text = element_text(angle = 0, hjust = 0, face = "bold"))
A few explanations:
We use dodged bars and matching dodged labels with position = "dodge2" (note that this requires ggplot_ggplot2_3.0.0, otherwise use position = position_dodge(width = 1.0)) and position = position_dodge(width = 0.9), respectively.
We use facet_wrap and force a one-column layout; strip labels are moved to the bottom.
We rotate the entire plot with coord_flip(expand = F), where expand = F ensures that left aligned (hjust = 0) facet strip texts align with 0.
Finally we tweak the theme to increase the overall aesthetic similarity.
You can try using the data from the other answer. Differences are: we use scales::percent to draw percents. We use ggpubr::theme_transparent() theme to tweak as less as possible.
df$perc <- c(.60, .36, .44, .41, .42, .57, .34, .52)
ggplot(df, aes(label, perc, label=scales::percent(round(perc,2)),fill= factor(type))) +
geom_col(position = position_dodge(0.9), show.legend = F) +
geom_text(aes(y=0), position = position_dodge(0.9), size=5, hjust=-0.1, color="white", fontface="bold") +
scale_y_continuous("",labels = scales::percent) +
coord_flip(expand = F) +
facet_wrap(~label,scales = "free", strip.position = "bottom", ncol = 1) +
ggpubr::theme_transparent() +
xlab("") +
theme(strip.background = element_blank(),
strip.text = element_text(size = 12, face = "bold",hjust=0))
Maybe using facet wrap and adjusting the style?
dat <- data.frame(perc = c(60, 20, 90, 30), col = rep(c("gr1", "gr2"), 2),
text = c(rep("text1", 2), rep("text2", 2)))
ggplot(dat, aes(y = perc, x = col, fill = col)) +
geom_bar(stat = "identity", position = "dodge") +
coord_flip() +
facet_wrap(~text, strip.position = "bottom", ncol = 1)
For the past hours I have tried to understand the whole design/theme/labelling concept around ggalluvial, but I failed.
Within minutes I was able to produce the kind of graph I want (thanks to the package ggalluvial), but I can't figure how to produce the correct labelling/theme I'd like to have.
This is where I am currently:
This is where I was initially:
To get you to understand where I am, here's a reproducible example
I used the following code:
library(ggalluvial)
ds <- as.data.frame(Titanic)
ggplot(ds,
aes(weight = Freq, axis1 = Sex, axis2 = Class)) +
geom_alluvium(aes(fill = Sex), width = 1/12) +
geom_stratum(width = 1/4, fill = "black", color = "grey") +
scale_x_continuous(breaks = 1:2, labels = c("Sex", "Class")) +
scale_fill_manual(name = "", values=c("#A0A0A0", "#494949")) +
ggtitle("Titanic Survival") +
theme_bw() +
geom_text(stat = "stratum", color="white",label.strata = TRUE,
angle=c(90,90,0,0,0,0) , size=6,
nudge_y=c(1,2,3,4,5,0)) +
theme(legend.position = "bottom",
title = element_text(size = 20),
legend.text = element_text(size = 20),
axis.text.y = element_blank(),
axis.text.x = element_text(size=20))
What I would like to change:
turn labels on the left vertically
done
make labels on the right not overlap (not visible with the Titanic data)
I tried nudging. But it may be more useful to place these legends outside the graph, maybe like on an axis?
remove y-axis labels
done
Understand with what command I can change each of the text elements size (title, legend, labels, axis labels)
dome
I am very happy for any help on this. Thank you.
You can try:
ggplot(ds,
aes(weight = Freq, axis1 = Sex, axis2 = Class)) +
geom_alluvium(aes(fill = Sex), width = 1/12) +
geom_stratum(width = 1/16, fill = "black", color = "grey") +
scale_x_continuous(breaks = 1:2, labels = c("Sex", "Class")) +
scale_fill_manual(name = "", values=c("#A0A0A0", "#494949")) +
ggtitle("Titanic Survival") +
theme_bw() +
geom_text(stat = "stratum", color="red",label.strata = TRUE, angle=c(0,0,45,45,45,45),size=5) +
theme(legend.position = "bottom",
title = element_text(size = 20),
legend.text = element_text(size = 20),
axis.text.y = element_blank(),
axis.text.x = element_text(size=20))
add a vector with the same length of labels like angle=c(0,0,45,45,45,45)
add axis.text.y = element_blank() in theme()
pending
Sizes via theme
via theme() such as x-axis labels
text in plot via size=5 in geom_text()