Fixing margins in ggplot2 - r

I have a plot whose margins are slightly askew and need to be removed. So there should be no empty grey along the bottom or at the left and right of the plot. The dots should go right against the axis's. I think part of the problems may be my last two annotation lines. I tried adding + theme(plot.margins = unit(c(0.1,0.1,0.1,0.1), "cm")) in the last line that defines my plot but this just returns an error:
Error: Theme element `plot.margins` is not defined in the element hierarchy.
`
pvalplot<-function(var, maintitle) {
pvalall<-as.data.frame(c(t(var)))
pvalall$Sample_Size<-c((1:(5*162)),(1:(11*162)),(1:(3*162)),(1:(5*162)),(1:(13*162)),(1:(3*162)),(1:(5*162)))
pvalall$Domain<-c(rep("Physical",5*162),rep("Perinatal",11*162),rep("Developmental",3*162),
rep("Lifestyle-Life Events",5*162),rep("Parental-Family",13*162),rep("School",3*162),
rep("Neighborhood",5*162))
pvalall$Domain <- factor(pvalall$Domain,
levels = c("Physical", "Perinatal", "Developmental",
"Lifestyle-Life Events", "Parental-Family",
"School","Neighborhood"))
pvalall[,1]<-ifelse(pvalall[,1]<1e-20,1e-20,pvalall[,1])
names(pvalall)[1]<-"P-Values"
pvalexp.labels= rep("",45*162)
for (i in c(1:45)){
j=i*162-81
pvalexp.labels[j]=rownames(var)[i]
} #makes list of empyt labels that w
p<-ggplot(pvalall,aes(x = 1:nrow(pvalall), y = -log10(pvalall[,1])))+
geom_point(aes(color = Domain,size=5),
alpha = 0.7, size=1)
p+ylab(expression(atop(" -log10(P-Values)")))+
ylim(0,20)+
xlab(element_blank())+
theme(legend.title=element_blank())+
scale_x_continuous( breaks=c(1:45)*162-81, labels = rownames(var))+
theme_classic()+
theme(axis.title.x = element_blank())+
theme(axis.ticks.x = element_blank())+
theme(axis.title.y = element_text(size = 25))+
theme(text = element_text(size=25))+
theme(legend.title=element_blank())+
theme(legend.position=c(0.8,0.7))+
geom_abline(slope=0,intercept=-log10(c(var)[astsa::FDR(c(var))]),linetype = "dashed")+
geom_abline(slope=0,intercept=5.2,linetype = "dashed")+
ggtitle(maintitle)+
theme(plot.title = element_text(hjust = 0.5))+
theme(
legend.box.background = element_rect(),
legend.box.margin = margin(6, 6, 6, 6))+
theme_update(axis.text.x = element_text(angle = 35, size = 6.5, vjust = 1, hjust=1, color = "black")) +
annotate("text", label = expression(paste("FDR P-value","=0.05")),size=5, x=1000,y=-log10(c(var)[astsa::FDR(c(var))])-0.5, color="black",parse=TRUE)+
annotate("text", label = expression(paste("Bonferroni P-value","=0.05")),size=5, x=1200,y=5.7, color="black",parse=TRUE)
}#end of plotting

You can insert a line
scale_y_continuous(expand = c(0, 0)) +
in your plot command chain.

Related

ggplot: Adding a plot outline with the axis ticks

I'm trying to create plots where the x-axis ALSO appears above the plot as well as the y-axis to the right of the plot. Both should contain the same ticks as the normal axis, but NOT the axis text. This should result in a "box" with helpful tick-marks around the plot. I would also like to have smaller ticks in-between my major ticks (that are labelled) that do not have a label. Here is a figure I made:
I also drew in pink what I would like to achieve in R:
]3
My code for this plot:
p <- p + xlab("") + ylab("") + theme(legend.position = "none") + theme(axis.ticks.length = unit(-0.25, "cm"), axis.text.x = element_text(size = 30, hjust=1)) + theme(axis.text.y = element_text(size=35, hjust = 1), strip.text = element_text(size=35), axis.title.y = element_text(size = 40), legend.text = element_text(size=30), axis.title.x = element_text(size=40), legend.title = element_text(size=45))
p <- p + theme(text = element_text(family = "Helvetica")) + scale_x_continuous(limits=c(-0.5, 25), breaks = c(0, 2, 4, 6, 8, 24)) + theme(legend.background = element_rect(color = "black", linetype = "solid")) + scale_colour_manual(values = cbpallette)
p <- p + theme(legend.key.size = unit(2.5, "cm")) + theme(axis.text.x = element_text(margin = margin(t = .5, unit = "cm")), axis.text.y = element_text(margin = margin(r = .5, unit = "cm")))
p
*** Edit ***
Here is updated code, using Stefans advise. The figure looks like so, the ticks are there, the axis are missing:
p <- p + xlab("") + ylab("") + theme(legend.position = "none") + theme(axis.ticks.length = unit(-0.25, "cm"), axis.text.x = element_text(size = 30, hjust=1)) + theme(axis.text.y = element_text(size=35, hjust = 1, angle=45), strip.text = element_text(size=35), axis.title.y = element_text(size = 40), legend.text = element_text(size=30), axis.title.x = element_text(size=40))
p <- p + theme(text = element_text(family = "Helvetica")) + scale_colour_manual(values = cbpallette)
p <- p + theme(axis.text.x = element_text(margin = margin(t = .5, unit = "cm")), axis.text.y = element_text(margin = margin(r = .5, unit = "cm")))
p
You could duplicate the axes using argument sec.axis = dup_axis() for both scales like so:
library(ggplot2)
ggplot(mtcars, aes(hp, mpg)) +
geom_point() +
scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL))

Animate bar chart error in last plot (gganimate)?

I created an animated bar chart but the label value is not right. I don't know why cum_2 in my data is an integer, but in the resulting gif the label text appears as a real number (example: 674.5... instead of 675).
library(tidyverse)
library(gganimate)
df <- data.frame(date = c(rep('2020-07-08',4), rep('2020-07-09',4),
rep('2020-07-10',4), rep('2020-07-11',4),
rep('2020-07-12',4)),
sub = rep(c("PYTHON", "SQL", "VBA", "R"),5),
cum_2 = c(659,609,454,450,659,609,468,450,670,609,478,450,670, 609,486,461,679,609,486,469),
rank = rep(c(1,2,3,4),5))
fill <- c('red','blue','green','orange') # example fill colors
df %>%
ggplot(aes(rank, y = cum_2,
fill = sub)) +
geom_col(alpha = 0.6)+
scale_fill_manual(values = fill) +
geom_text(aes(y = 0,
label = paste(sub, " ")),
vjust = 0.2,
hjust = 1) +
transition_states(states = date,transition_length = 4, state_length = 1) +
geom_text(aes(y = cum_2,
label = round(cum_2,0),
hjust = 0,
size = 12)) +
scale_x_reverse() +
coord_flip(clip = "off", expand = FALSE) +
guides(color = FALSE, fill = FALSE) +
theme(axis.line=element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
legend.position="none",
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
panel.grid.major.x = element_line( size=.1, color="grey" ),
panel.grid.minor.x = element_line( size=.1, color="grey" ),
plot.title=element_text(size=25, hjust=0.5, face="bold", colour="grey", vjust=-1),
plot.subtitle=element_text(size=18, hjust=0.5, face="italic", color="grey"),
plot.caption =element_text(size=8, hjust=0.5, face="italic", color="grey"),
plot.background=element_blank(),
plot.margin = margin(2,2, 2, 4, "cm")) +
labs(title = 'MCI Vietnam : {closest_state}',
subtitle = "Number of students") +
view_follow(fixed_x = TRUE) +
enter_fade() +
exit_shrink() +
ease_aes('sine-in-out') -> anim
# gif
animate(anim, nframes = length(unique(df$date)),
detail = 5,
fps = 5,
# duration = 20,
renderer = gifski_renderer("file.gif"))
Last plot in gif file here:
Thanks all for read & support me.
Since the y position of the bars is tweened in the animation (cum_2 in your data frame), and the label position and text are based on cum_2, it will also get tweened and the result is that you have numbers with lots of decimal places appearing as a result.
Luckily, the fix is pretty easy: just force your label to be evaluated as.character(). Change your geom_text line to read as follows, and that fixes the issue:
geom_text(aes(y = cum_2, label = as.character(round(cum_2,0)),
hjust = 0, size = 12))
Here's the result (saved with duration=5):
*FYI: your code was missing the colors you used, so here I defined fill=c('red','blue','green','orange').

Plot legend to move left ggplot

I like to move the legend a bit further on the left But I am not getting how to do it.
Secondly, I also want to reduce the space between axis label and legend too
Can you please suggest something
the code is given below that I am using
The image of the graph is in the link below
"tooltip"
ggplot(Q6_m, aes( choice,temp,fill=Answer ))+
geom_bar(position = position_stack(reverse = TRUE), stat="identity") +
coord_flip() +
xlab("") +
ylab("Number of responses") +
scale_fill_brewer(type = "div") +
theme(axis.text=element_text(size=8),
axis.title=element_text(size=8,face="bold"), legend.title = element_blank(),
legend.text=element_text(size=7)) +
ggtitle("Q6:Rate your ability to perform the following procedures WITHOUT attending assistance?")+
theme(plot.title = element_text(color = "black", size = 7.5, face = "bold", hjust = 1))+
facet_wrap(~gender,scales = "free_x")+
theme(legend.position="bottom", legend.direction = "horizontal",legend.key.size = unit(0.5,"line")
)
You should use legend.justification to get the legend on the left side of the plot and legend.margin to reduce the space between axis labels and the legend:
ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species))+
geom_boxplot()+
theme(legend.position = "bottom",
legend.justification = c(0,1),
legend.margin = margin(t = -15, r = 0, b = 0, l = 0, unit = "pt"))
Does it answer your question ?

R: Two y-axes plot using scale_y_continuous(sec.axis) and coord_trans(log10)

I am trying to plot a 2y-axes plot; on the left, the actual values, and on the right, the % values. In addition to this, I need to apply coord_trans on the left y-axis for a better visualization of small values. However, when I do it, the labels on the right do not show up.
Here the data (example)
Here the code
DAXIS <- ggplot(x1, aes(hour, value_T, colour=season, linetype = variable)) +
geom_line(size = 1) +
scale_linetype_manual(c("var"), values=c("solid", "dashed", "dotted"))+ # here to change one name
geom_point(aes(shape = season), size = 1)+
labs(x = "hour", y = "T") +
scale_x_continuous(breaks = c(0, 6, 12, 18, 23), labels= c(0, 6, 12, 18, 24))+
scale_y_continuous("T",
sec.axis = sec_axis(~./2.341598, name = " [%] ",
breaks=c(0.2135294, 0.4270588, 0.6405882, 0.8541176,1),
labels = function(b) { paste0(round(b * 100, 0), "%")}))+
#coord_trans(y = "log10", breaks=c(0.5,1,1.5,1.903738), labels = c(0.5,1,1.5,1.9))+ # attemp 1
#coord_trans(y = "log10")+ # attemp 2
scale_color_aaas()+
theme_bw()+
theme(legend.direction = "horizontal", legend.position = "bottom", legend.key = element_blank(),
legend.background = element_rect(fill = "white", colour = "gray30")) +
theme(legend.position="bottom",
text=element_text(size=18),
axis.text.x = element_text(size=15),
axis.text.y = element_text(size=15))
DAXIS
Here the output without coord_trans
Here the output with coord_trans
Any help is very much appreciated

Can this type of plot be done with ggplot2?

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)

Resources