Making facet_wrap label cover all related panels in ggplot - r

I was wondering, is there a way to make facet_wraps() labels cover all of the related columns in ggplot. Here is a example to show what I mean:
library(tidyverse)
p <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
p + facet_wrap(~ vs+cyl, labeller = label_value)
As you can see, in the previous plot, the labels 0 and 1 are present above all of the columns, separately. I would like to modify it in a way that there is only one 0 above the first row of columns and only one 1 over the second row of columns.

Related

Issue: Plot alpha values scaling with Y-Axis/number of observations in ggplot facets

I haven't found anyone else with this issue. Here is my plot:
facet plot
Why are there different alpha values for each facet?
As you can see, the alpha value of the geom_rect() elements seems to scale with the y-axis or number of observations, maybe because I have set these to "free_y" in the facet_wrap() argument. How can I prevent this from happening?
Here is my code:
plot_data %>%
ggplot(aes(Date, n)) +
geom_rect(data= plot_data, inherit.aes = FALSE,
aes(xmin=current_date - lubridate::weeks(1), xmax=current_date, ymin=-Inf, ymax=+Inf),
fill='pink', alpha=0.2) +
geom_col() +
facet_wrap(~Type, scales = "free_y") +
xlab("Date") +
ylab("Count") +
theme_bw() +
scale_y_continuous(breaks = integer_breaks()) +
scale_alpha_manual(values = 0.2) +
theme(axis.text.x=element_text(angle=90, hjust=1))
Cheers!
TL;DR - It seems this is probably due to overplotting. You have 5 rect geoms drawn in the facet, but probably more than 5 observations in your dataset. The fix is to summarize your data and associate geom_rect() to plot with the summarized dataset.
Since OP did not provide an example dataset, we can only guess at the reason, but likely what's happening here is due to overplotting. geom_rect() behaves like all other geoms, which is to say that ggplot2 will draw or add to any geom layer with every observation (row) in the original dataset. If the geoms are drawn across facets and overlap in position, then you'll get overplotting. You can notice that this is happening based on:
Different alpha appearing on each facet, even though it should be constant based on the code, and
The fact that in order to get the rectangles to look like "light red", OP had to use pink color and an alpha value of 0.2... which shouldn't look like that if there was only one rect drawn.
Representative Example of the Issue
Here's an example that showcases the problem and how you can fix it using mtcars:
library(ggplot2)
df <- mtcars
p <- ggplot(df, aes(disp, mpg)) + geom_point() +
facet_wrap(~cyl) +
theme_bw()
p + geom_rect(
aes(xmin=200, xmax=300, ymin=-Inf, ymax=Inf),
alpha=0.01, fill='red')
Like OP's case, we expect all rectangles to be the same alpha value, but they are not. Also, note the alpha value is ridiculously low (0.01) for the color you see there. What's going on should be more obvious if we check number of observations in mtcars that falls within each facet:
> library(dplyr)
> mtcars %>% group_by(cyl) %>% tally()
# A tibble: 3 x 2
cyl n
<dbl> <int>
1 4 11
2 6 7
3 8 14
There's a lower number of observations where cyl==6 and cyl==4 has lower observations than cyl==8. This corresponds precisely to the alpha values we see for the geoms in the plot, so this is what's going on. For each observation, a rectangle is drawn over the same position and so there are 7 rectangles drawn in the middle facet, 14 on the right facet, and 11 on the left facet.
Fixing the Issue: Summarize the Data
To fix the issue, you should summarize your data and use the summarized dataset for plotting the rectangles.
summary_df <- df %>%
group_by(cyl) %>%
summarize(mean_d = mean(disp))
p + geom_rect(
data = summary_df,
aes(x=1, y=1, xmin=mean_d-50, xmax=mean_d+50, ymin=-Inf, ymax=Inf),
alpha=0.2, fill='red')
Since summary_df has only 3 observations (one for each group of cyl), the rectangles are drawn correctly and now alpha=0.2 with fill="red" gives the expected result. One thing to note here is that we still have to define x and y in the aes(). I set them both to 1 because although geom_rect() doesn't use them, ggplot2 still expects to find them in the dataset summary_df because we stated that they are assigned to that plot globally up in ggplot(df, aes(x=..., y=...)). The fix is to either move the aes() declaration into geom_point() or just assign both to be constant values in geom_rect().

R boxplot color not changing

I'm making a box-and-whisker plot in R (y-axis # of reads and x-axis of 4 discrete conditions). I'm trying to switch the order in which the discrete conditions appear and to change them from the default white fill to a color of my choosing using the code below. I can get the order to change, but the color continues to stay white. I also have no idea why R cuts off my plot.
library(ggplot2)
capture_data = read.csv("tcp_for_r_plots.csv")
p <- ggplot(capture_data, aes(x=Protocol, y=raw_reads)) + geom_boxplot()
p <- p + scale_x_discrete(limits=c("Standard","TD-60","TD-55","TD-50"))
p <- p + scale_fill_manual(values=c("#999999","#FFFF00","#33FFFF","#FF33CC"))
Attached is the output I keep getting - no color change.
fill color: You need to add the fill option to the geom_boxplot() function as shown below (instead of using the scale_fill_manual function):
+ geom_boxplot(fill=c("#999999","#FFFF00","#33FFFF","#FF33CC"))
Order: the order is based on the alphabetical order of the factor values (Protocol). One solution is to recode the factor levels into the the order you want before running the generating the plot.
p <- ggplot(capture_data, aes(x=Protocol, y=raw_reads, fill=Protocol)) +
geom_boxplot() +
scale_x_discrete(limits=c("Standard","TD-60","TD-55","TD-50")) +
scale_fill_manual(values=c("#999999","#FFFF00","#33FFFF","#FF33CC"))
Add the colors in "fill" argument in ggplot:
p <- ggplot(capture_data, aes(x=Protocol, y=raw_reads)) + geom_boxplot()
should be
p <- ggplot(capture_data, aes(x=Protocol, y=raw_reads, fill = Protocol)) + geom_boxplot()
For example,
ggplot(mtcars, aes(x= as.factor(cyl), y=mpg, fill=as.factor(cyl))) + geom_boxplot()
gives me

share label in ggplot facet_wrap to avoid repetition

This code
library(ggplot2)
ggplot(mtcars, aes(mpg, hp)) +
facet_wrap(am ~ cyl, ncol = 6) +
geom_point()
produces the following graph
The variable "am" has two values (0 and 1) that are repeated 3 times each. I wonder whether it is possible to include a single strip with the value 0 centered (and the same for the value 1).

ggplot 2 - Change legend categories with numeric values (no factors)

Suppose I work with the mtcars data set. I would like to set the size of the points according to the weight (wt). If I do that as shown below, R/ggplot2 will give me a legend with 4 categories (2,3,4,5).
library(ggplot2)
mtc <- mtcars
p1 <- ggplot(mtc, aes(x = hp, y = mpg))
p1 <- p1 + geom_point(aes(size = wt))
print(p1)
How can I change the scale/names/categories of the legend. I found information on how to do that if the "categories" would be factors, but I don't know how to do this with numeric values. I need to keep them numeric otherwise it doesn't work with the size of the dots anymore.
My real data set has about 100 values for wt (everything from 1-150) and I want to keep 5 values. (ggplot 2 gives me 2 -> 50 and 100)
1) How can I change the scale of that legend? In the mtc example for example I just want 2 points of size 2 and 5
2) I was thinking about making categories such as:
mtc$wtCat[which(mtc$wt<=2)]=1
mtc$wtCat[which(mtc$wt>2 & mtc$wt<=3)]=2
mtc$wtCat[which(mtc$wt>3)]=3
p1 <- ggplot(mtc, aes(x = hp, y = mpg))
p2 <- p1 + geom_point(aes(size = wtCat), stat="identity")
print(p2)
and then just rename 1,2,3 in the legend into <=2, 2-3 and >3 but I didn't figure out how to do that as well.
Thank you so much.
You can use scale_size_continuous() and with argument breaks= set levels you want to see in legend and with argument labels= change how legend entries are labelled.
ggplot(mtcars,aes(hp,mpg,size=wt))+geom_point()+
scale_size_continuous(breaks=c(2,5),labels=c("<=2",">2"))

how to have x-axis labels in multicolumn ggplot with facet_wrap?

When trying to plot something like this:
library(ggplot2)
d <- ggplot(diamonds, aes(carat, price)) +
xlim(0, 2) + geom_point()
d + facet_wrap(~ color)
You will notice that the x-axis labels only show up for the first column. I would like them to repeate on the second and third column. Is this possible?
If on the facet_wrap I use the option scales="free",
d + facet_wrap(~ color, scales="free")
then i get x-axis labels on all plots, which I also don't want. I want only labels in the bottom row repeating across columns
If the number of panels to be plot is such, that all columns have the same number of plots, the axis gets repeated in the way I want. But I can't always have the right number of panels for that.
With version 2.2.0 of ggplot this problem is fixed.
see https://www.rstats-tips.net/2016/11/ggplot2-x-axis-scale-now-available-on-all-facet-columns/

Resources