Equalize size of plots placed in juxtaposition by grid.arrange - r

I gathered three geom_bar() plots in one plot by grid.arrange:
I removed the y axis of the two right plots (Q2,Q3) and kept the y axis of Q1 as a common axis. Subsequently, I change plot.margin a little bit to obtain a continuous x axis. Although this worked fine, it bugs me that the leftmost plot is smaller than the remaining two plots. I highlighted the difference in size by plotting the y axis again. I tried to fix this by changing plot.margin but without success. Is there any way to equalize the size of the three plots?

The package patchwork (https://github.com/thomasp85/patchwork) automatically balances the size of the plots while aggregating the plots

Related

How to have geom_point and geom_bar side by side and with facet_wrap

I am trying to combine a scatterplot with a bar plot. The bar plot should be on the right side of the scatterplot of each corresponding group specified in facet wrap. The two plots have the same unit on the y axis but the scaling of the bar might need to be adjusted so the barplot it's not too tall.
Here's an example.
data(mpg)
So far I have tried this, but I would the bar should be outside the scatterplot area. Additionally, in my data the x axis in the barplot is a factor with two levels, so it has a discrete scale and my scatterplot has a continuous x scale.
ggplot()+geom_bar(data=mpg,aes(x=10,y=displ,fill=trans),stat='identity',position='stack')
+geom_point(data=mpg,aes(x=displ,y=displ))+facet_wrap(~cyl)
Can I achieve to plot these two plot types side-by-side or do I have to use something like cowplot? I think that if I have to combine plots outside ggplot I will not be able to use factor_wrap, so I guess I have to do a for loop for each factor level and then combine everything?

How to align y axis by 0 between plots with plot_grid function in R?

I made several weekley plots of different gaseous compounds (BVOCs) with ggplot and I put them together with plot_grid function. Obviously compounds have different scales and Y axis are not aligned.
I wish align them by zero on Y axis.
I think that I can avoid to share the dataset and the single plots code, because the point is on plot_grid function that put them together.
Here the plot_grid function that I used:
plot_grid(metmax,acetalmax,formicmax,acetmax,nrow = 4,align = "hv",rel_widths= c(1,1,1,1),rel_heights = c(1.2,1.2,1.2,1.2))
Here an example of how appear my final plot with Y axis out of phase.
If I understand it correctly, you want the line at y=0 to appear at the same height in all plots. That would require them all to have the same range and, by consequence, the same scale.
You can add to your ggplot() call the following:
+ ylim(min_value, max_value)
min_value and max_value can be calculated by the script by looking at the range of values occurring in your plot data.
https://ggplot2.tidyverse.org/reference/lims.html

How to expand horizontal date scale while keeping legend within plot w/ asymmetrical vertical expansion

I am using ggplot2 to make several area plots of time series. To my eye, the plots look better if the time series covers the entire x axis, the height of the highest area is about 5% - 10% below the top of the plot area, and the legend is situated in the lower right corner of the plot.
Let base.plot be a base plot that labels the x axis and formats its tick marks, adds NBER recession bars, and locates the legend in the lower right corner of the plot itself with:
base.plot <- base.plot + theme(
legend.justification = c(1,0),
legend.position = c(1,0),
legend.title = element_blank()
)
This seems to work fine with my line plots, but on the area plots the legend box sticks out to the right and below the plot itself. Instead, its lower right corner should be at the lower right corner of the plot area. How can I fix this?
To change the plot's extent relative to its axes, I tried using the expand argument to expand the plot horizontally and vertically. Documentation for this argument leaves something to be desired, to say the least:
expand
A numeric vector of length two giving multiplicative and additive expansion constants. These constants ensure that the data is placed some distance away from the axes. The defaults are c(0.05, 0) for continuous variables, and c(0, 0.6) for discrete variables.
Is it too much to ask for the formula so we can know what the multiplicative and additive constants actually do? Otherwise, how else can we know how to set them? The above description appears in the documentation for scale_x_date; is it too much to ask for some mention of the defaults for date variables?
Flying blind, thanks to the useless documentation, I tried the solution for continuous variables:
scale_x_date(expand = c(0,0)),
But this just scrunched up the plot towards the right of the chart. So where can I learn about using scale_x_date with the expand argument?
As for the vertical axis, scale_y_date(expand = c(0,0)) did bring the bottom of the area plots down to the x-axis. But the top is too high. Somewhere I saw that a modification to the scale_y_date code now allows four arguments, two for the lower bound and two for the upper one. I tried this too, but there's no discernible difference from the plot using only the two parameters.
So, how can I get the lowest area plot to sit on the x axis and the highest point to be about 0.5 in from the top?

Customise x-axis ticks

I have a very large data frame (2 columns) in terms of records. I have plotted the graph in ggplot2. The X axis is the time and the Y axis is values. Over a specific interval from time 50 to 60, I want to make the ticks increments to be smaller such as (50,51,51,53,...59,60). For the rest of the axis, it is fine to have the ticks incremented by 10. So,I would expect to have X-axis values like :
10,20,30,40,50,51,52,53,54,55,56,57,58,58,60,70,80,90,..190,200.
I know, I can modify the ticks through scale_x_continuous by using breaks and minor_breaks. However, I'm not getting the expected output. Here is my try:(note: have created data just for example as my data is very large).
data:
-----
x<-seq(1:200)
y<-seq(51,250,by=1)
df<-data.frame(x=x,y=y)
code:(Update based on #Didzis Elferts suggestion)
-----
ggplot(data=df, aes(x,y))+geom_line(size=1.6)+
scale_x_continuous( breaks=c(10,20,30,40,seq(50,60,by=2),seq(70,200,10))
,minor_breaks=seq(50,60,by=2) )+
+theme(axis.text.x=element_text(size=16),axis.text.y=element_text(size=16))+
+theme(axis.title.x=element_text(size=16),axis.title.y=element_text(size=16))+
+theme(axis.ticks.x = element_line(size = 1))+xlab("Time")+ylab("value")
+theme(axis.ticks.length=unit(0.8,"cm"))
Based on the suggestion below, the only problem now is the values of X-axis during the interval between 50-60 is not clearly appeared.
Any suggestions to make it clear!!
With argument minor_breaks= you set the minor gridlines. To set numbers under the x axis all number should be provided with argument breaks=.
ggplot(data=df, aes(x,y))+geom_line(size=1.6)+
scale_x_continuous(breaks=c(10,20,30,40,seq(50,60,by=1),seq(70,200,10)),
minor_breaks=seq(50,60,by=1))
For the second problem - you set axis.ticks.x=element_line(size=5) inside theme() - that makes your axis ticks wider so they appear as small rectangles. If you want to make axis ticks longer use axis.ticks.length=.
+theme(axis.ticks.length=unit(0.5,"cm"))

Set ticks margin on one axis (ggplot2)

When plotting graphs with categorical variables (such as boxplots) with long names, the names have to be shifted using the theme command in ggplot2, then the distance between the axis ticks and the text can be set as well yet this distance is reflected on both axis when it is some time only necessary on one axis. Below some sample code:
df<-data.frame(X=rnorm(50,0,10),Y=c(rep("Some Text",25),rep("Some Larger Text That Takes Space",25)))
#classical boxplots
ggplot(df,aes(x=Y,y=X))+geom_boxplot()+theme(axis.text=element_text(size=20),axis.text.x=element_text(angle=45))
#the x axis labels need to be shifted downwards
ggplot(df,aes(x=Y,y=X))+geom_boxplot()+theme(axis.text=element_text(size=20),axis.text.x=element_text(angle=45),axis.ticks.margin=unit(4,"cm"))
#now they are shifted but there is unnecessary space on the y-axis
How can we set axis.ticks.margin to act on only one axis?
Try this for example :
library(grid)
axis.ticks.margin=unit(c(4,-4),'cm'))
So, the ggplot2 call becomes:
ggplot(df,aes(x=Y,y=X))+
geom_boxplot()+
theme(axis.text=element_text(size=20),
axis.text.x=element_text(angle=45),
axis.ticks.margin=unit(c(4,-4),'cm'))

Resources