How to change the position of one of the facet_nested labels? - r

I have a plot for which I would like to place one facet label in the top and the other one on the left side of the plot. However, I don't know if that is possible or if I should do it in an other way. Below I show a fake example to play with:
library(ggplot2)
library(ggsci)
library(ggthemes)
library(ggh4x)
df <- data.frame(x=c(0,0,0.3,0.8,1.5,3,5,7,9,13,15,20,28),
y=c(0,0,0.3,0.8,1.5,3,5,7,9,13,15,20,28))
df$Method <- "Pearson"
df$ID <- "A"
Plot <- ggplot(df, aes(x=x, y=y)) +
geom_point(size=.8) +
theme_hc() +
theme(strip.background = element_rect(colour = "black", fill = "white",
size = 1.5, linetype = "solid"),
axis.title.x =element_blank(),
axis.title.y =element_blank(),
axis.text.x = element_text(angle = 0, hjust = 0.5,size = 10.5, face="bold"),
axis.text.y = element_text(angle = 0, hjust = 0.5,size = 10.5),
strip.text.x = element_text(size = 9),
strip.text.y = element_text(size = 13),
axis.line = element_line(),
panel.grid.major= element_blank(),
panel.grid.minor = element_blank(),
legend.text=element_text(size=9),
legend.title = element_text(size=10,face="bold"),
legend.key=element_blank(),
legend.justification = c(0.5,0),
legend.position = "right",
panel.border = element_blank(),
strip.placement = "outside",
plot.title = element_text(size = 16, hjust = 0.5),
strip.switch.pad.grid = unit('0.1', "cm")) +
labs(x= '\nTime delay (modifiable device)',y=expression(R^{2})) +
guides(color=guide_legend(override.aes=list(fill=NA))) +
scale_y_continuous(limits = c(0., 30), breaks = c(5, 15,25)) +
facet_wrap(Method~ID) +
scale_color_jco()
Plot
I would like to place the A label in the left part of the plot? Does anyone know how to do it?
Thanks

I'm sorry for stripping away most of the plotting code, but the following captures the essence and requires less additional packages.
facet_wrap() only puts strips on one side of the plot. If you need two sides with strips, you can use facet_grid(). To place the strip on the left, you can use the switch = 'y' argument.
library(ggplot2)
df <- data.frame(x=c(0,0,0.3,0.8,1.5,3,5,7,9,13,15,20,28),
y=c(0,0,0.3,0.8,1.5,3,5,7,9,13,15,20,28))
df$Method <- "Pearson"
df$ID <- "A"
ggplot(df, aes(x=x, y=y)) +
geom_point(size=.8) +
facet_grid(Method~ID, switch = 'y')

Related

Add only one panel border line between facets in ggplot

For the following sample df
df = data.frame(x = c(2,3,4),y = c(4,5,6),group.a= c("1","1","2"),group.b = c("a","b","b"))
I want to just add a horizontal line in-between the y axis facet grids and after browsing different posts here I have tried using the panel.border = element_rect() argument however that gives me all four borders (top, right, bottom, left)
ggplot(df,aes(x=x,y=y)) + facet_grid(group.a~group.b) + theme_minimal() +
theme(legend.position = "bottom",
legend.title = element_blank(),
legend.direction = "horizontal",
legend.margin = margin(-20,0,0,0),
panel.grid = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = .5)
axis.text.x = element_blank(),
axis.line.y = element_line(size = .5),
axis.line.x = element_line(size = .5),
strip.placement = "outside")
Is there a way to just have the bottom and left border of the panel borders? Thanks!
There aren't any theme elements that fit the bill here; you would need custom annotations. Fortunately, annotation_custom applies to each panel, so this can be done with a couple of lines of code
library(ggplot2)
df = data.frame(x = c(2,3,4),y = c(4,5,6),
group.a= c("1","1","2"),group.b = c("a","b","b"))
ggplot(df,aes(x=x,y=y)) +
facet_grid(group.a~group.b) +
geom_point(col = "white") +
theme_minimal() +
annotation_custom(grid::linesGrob(y = c(0, 0), gp = grid::gpar(lwd = 3))) +
annotation_custom(grid::linesGrob(x = c(0, 0), gp = grid::gpar(lwd = 3))) +
theme(panel.grid = element_blank(),
strip.placement = "outside",
axis.text.x = element_blank())

Adjusting the y-tick labels with hjust not working

I want to move the y-axis tick labels to the left (as i did with the axis.text.y to the bottom).
The weird thing is with hjust = -2.5, although the theme_set() part runs without errors, the text on the y-axis does not get moved. However, vjust = 2does affect the y labels just fine.
I am creating a bug with all my options in the theme?
library(tidyverse)
library(ggplot2)
theme_set(
theme_classic() +
theme(
axis.ticks.length = unit(-0.25, "cm"),
axis.text.x = element_text(vjust = -2.5),
axis.text.y = element_text(hjust = -2.5), # this does not do anything.
# axis.text.y = element_text(vjust = -2.5), # while vjust does affect the text placement.
axis.line = element_blank(),
panel.grid.major.y = element_line(linetype = 2),
plot.title = element_text(hjust = 0.5),
text = element_text(family = "serif"),
legend.justification = c(1, 1),
legend.position = c(1, 1),
panel.border = element_rect(fill = NA, size = 2)))
mpgdat <- tibble(mtcars)
mpgdat %>% ggplot(aes(disp, mpg)) + geom_point()
This does seem to be a bug in how hjust works for axis text. A workaround would be to use margin instead of hjust:
theme_set(
theme_classic() +
theme(
axis.ticks.length = unit(-0.25, "cm"),
axis.text.x = element_text(vjust = -2.5),
axis.text.y = element_text(margin = unit(c(0,0.4,0,0), "cm")),
panel.border = element_rect(fill = NA, size = 2)))
'
Hat tip to this related answer: How do I make my axis ticks face Inwards in ggplot2

How to draw an empty ggplot with just the legend?

My question is very similar to this question, but it's not the same.
I am looking for a way to create an empty ggplot with just the legend. However, in contrast to the autohor of the question I linked at the top, I actually need to create just the legend with no plot area included in the image.
I tried the following code:
ggplot(NULL, aes(color = ""))+
geom_blank()+
scale_color_manual(values = "black", labels = "Something")+
guides(color = guide_legend())+
theme(legend.box.background = element_rect(color = "black"))
But I'm getting the opposite of what I want - I am getting an empty plot area with no legend, like this:
And I would like my end result to look like this (I drew this in Paint):
Any help would be appreciated!
You can make a normal plot, then play with theme to achieve the desired result.
library(ggplot2)
ggplot(data.frame(x = 1, y = 1, colour = 'Something'), aes(x, y, fill = colour))+
geom_point(alpha=0, shape = 0)+ # completely transparent rectangular point
scale_fill_manual(values='black', drop=FALSE) +
guides(fill = guide_legend(override.aes = list(alpha=1, size = 40)))+ # showing the point in the legend
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.position = c(0.5, 0.5), # move the legend to the center
legend.title = element_blank(),
legend.text = element_text(size = 40),
legend.key = element_rect(fill='NA'),
panel.grid = element_blank(),
panel.border = element_rect(colour = "black", fill='white', size=1)
)
Get the legend how you want it to look, then extract it with cowplot::get_legend:
library(grid)
library(cowplot)
library(ggplot2)
grid.newpage()
grid.draw(get_legend(
ggplot(data.frame(x = 1, y = 1), aes(x, y, fill = "Something")) +
geom_col(size = 20)+
scale_fill_manual(values = "white", labels = "Something", name = "") +
theme_bw() +
theme(legend.box.background = element_rect(color = "black"),
legend.title = element_text(size = 30),
legend.key.size = unit(60, "points"),
legend.text = element_text(size = 24),
legend.key = element_rect(colour = "black"),
legend.box.margin = margin(20, 20, 20, 20))))

How to move legend up closer to the x-axis label in ggplot2

I have am creating a function to create dumbbell graphs with the legend positioned on the bottom. However, it's too far away from the title of the x-axis. I wanted to move it up slightly so that it is 10 pixels below the x-axis.
Here's the code:
vertical_theme = theme_bw(base_family = "Georgia") +
theme(
panel.border = element_rect(color = "black", fill=NA),
axis.title.x = element_text(hjust=0.5, size = 10, margin=margin(t=10, b=10)),
axis.text.y = element_text(size=10, margin=margin(r=10), color="black", hjust=0),
axis.text.x = element_text(size=10, margin=margin(t=10), color="black"),
axis.title.y = element_blank(),
legend.title = element_blank(),
legend.position= "bottom",
legend.text = element_text(size = 10, margin = margin(r = 10)),
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank(),
panel.grid.major.x = element_line(size=1),
panel.grid.minor.x = element_blank(),
plot.margin = margin(10, 30, 10, 10, "pt"))
dumbbell = function(df) {
ggplot(df, aes(pct_responses, Domain)) +
geom_line(aes(group=Domain)) +
geom_point(aes(shape=race), size=5, color="#3bbae0" ) +
vertical_theme +
scale_shape_manual(labels = c("Black Students", "White Students"),
values=c(15, 19)) +
scale_x_continuous(expand = c(0, 0),
limits=c(0,100),
breaks = seq(0, 100, by=20),
labels = function(x) paste0(x,"%")) +
labs(x = "% of Responses") +
scale_y_discrete(labels = wrap_format(40))
}
dumbbell(df)
Here's a screenshot (labels on y-axis removed because that data isn't public yet):
I tried to adjust the legend.position manually with legend.position = c(0.5, 0) (playing around with various different numbers) but then the legend overlaps with "% of Responses."
Use theme(legend.margin=margin(-10, 0, 0, 0)) to move the legend up. Adjust -10 as needed.

Set y limits in Bar Chart ggplot2

I have created a bar chart which shows the sales of products in a particular category. This is the bar chart. As you can see it is not very clear so I am trying to set limits for the Y axis.
I create the bar chart with the following line:
bakerySales <- ggplot(sales_bakery, aes(ProductName, ProductSales))+
stat_summary(fun.y=sum,geom="bar",colour="red",fill="red",show.legend =
FALSE)
I then go on to apply a theme to the bar chart using:
bakerySales <- bakerySales +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_text(colour = "black", size = 14, angle = 60,
hjust = 1),
axis.text.y = element_text(colour = "black", size = 14),
panel.background = element_rect(fill = "white"),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
axis.line = element_line(colour = "black", size = 1),
legend.position = "none",
plot.title = element_text(lineheight = 8, face = "bold"))
I have tried to set the limits for the y axis using:
bakerySales <- bakerySales + ylim(5000,10000)
When I do this I lose the content of the bar chart, It looks like this.
Can someone please tell me where I am going wrong.
Thanks
If you want to zoom in on specifix ylimits, you could use the coord_cartesian function. I do not have the bakerysales dataset, this is an example using mtcars data:
ggplot(mtcars, aes(x = gear, y = qsec)) +
stat_summary(fun.y=sum,geom="bar",colour="red",fill="red",show.legend = FALSE) +
coord_cartesian(ylim = c(200, 300))
Maybe you want
+ coord_cartesian(ylim = c(5000,10000))
df <- data.frame(x = c("a","b"), y = c(1000, 2000))
ggplot(df, aes(x=x,y=y)) +
geom_bar(stat="identity") +
coord_cartesian(ylim = c(500,3000))

Resources