Modifying Aesthetics - ggplot2 - r

I am trying to learn ggplot2 and have made below plots:
Using this code:
library(ggplot2); library(gridExtra)
gg <- ggplot(mydata,aes(x=Level))
plot1 <- gg + geom_line(aes(y=Experience,colour="xp"),size=1) +
labs(title="xp")
g <- ggplot(mydata,aes(x=Level))
plot2 <- g + geom_line(aes(y=Experience,colour="xp"),size=1) + geom_line(aes(y=Accu,colour="accu"),size=1) +
labs(title="xp vs Accumulated")
grid.arrange(plot1,plot2,ncol=2)
Where mydata is a data frame containing 3 columns (Level, xp and accu) and 30 rows.
What I am wondering is:
How to get the y-axis on the left-hand plot to have the same form as the
right-hand plot.
How to make the color of "xp" the same in both plots
without removing the descriptions of what the lines represent.

How about this (with some random data)?
library(ggplot2)
library(gridExtra)
library(scales)
gg <- ggplot(mydata,aes(x=Level))
plot1 <- gg + geom_line(aes(y=Experience,colour="xp"),size=1) +
labs(title="xp") + scale_y_continuous(labels = comma) +
scale_colour_manual(values = c("red"))
g <- ggplot(mydata,aes(x=Level))
plot2 <- g + geom_line(aes(y=Experience,colour="xp"),size=1) +
geom_line(aes(y=Accu,colour="accu"),size=1) +
labs(title="xp vs Accumulated") + scale_y_continuous(labels = comma) +
scale_colour_manual(values = c("blue", "red"))
grid.arrange(plot1,plot2,ncol=2)

Related

Control size of subplots created with patchwork - code improvement

I want to make a multipanel figure containing multiple labeled plots. My plots are produced in ggplot2 & I would like to arrange them with patchwork.
I want to combine two subplots in the first row, followed by two other plots arranged one plot per row:
plot3 + plot4 - both in row #1
plot1 - in row #2
plot2 - in row #3
Here is a dummy example to illustrate the problem:
```{r, fig.width=10, fig.height=13}
library(ggplot2)
library(patchwork)
#Dummy plots
plot1 <- ggplot2::ggplot(data = mpg, aes(x = class, fill=drv)) +
geom_bar(aes(y = ..count..)) + ggplot2::ggtitle("Plot1")
plot2 <- ggplot2::ggplot(data = mpg, aes(x = displ, y = hwy, color=class)) +
geom_point()+ ggplot2::ggtitle("Plot2")
plot3 <- ggplot2::ggplot(data = mpg, aes(x = cty)) +
geom_density()+ ggplot2::ggtitle("Plot3")
plot4 <- ggplot2::ggplot(data = mpg, aes(x = cty, y=drv, fill = fl)) +
geom_col()+ ggplot2::ggtitle("Plot4")
# this works, but it is not the desired layout
final <- plot1 + plot2 + {plot3 + plot4 + patchwork::plot_layout(ncol=2)} +
patchwork::plot_layout(ncol=1,heights = unit(c(4, 7, 2),c('cm')))
plot(final)
#this does not work
final2 <- {plot3 + plot4 + patchwork::plot_layout(ncol=2)} + plot1 + plot2 +
patchwork::plot_layout(ncol=1, heights = unit(c(2, 4, 7),c('cm')))
print(final2)
```
This is the output I can produce, but this is not what I want:
And this is the picture I would like to obtain:
Some of my other attempts:
#this does not work either
up_patch <- plot3 + plot4 + patchwork::plot_layout(ncol=2)
final2 <- up_patch + plot1 + plot2 + patchwork::plot_layout(ncol=1, heights = unit(c(2, 4, 7),c('cm')))
print(final2)
#and this as well
up_patch <- plot3 + plot4 + patchwork::plot_layout(ncol=2, heights= unit(2,c('cm')))
bottom_patch <- plot1 + plot2 + patchwork::plot_layout(ncol=1, heights = unit(c(4, 7),c('cm')))
final2 <- up_patch + bottom_patch
print(final2)
# THIS WORKS but needs improvement
final_desired <- (plot3 | plot4) / plot1 + plot2
print(final_desired)
In the last attempt I was able to produce the desired layout, however I would like to be able to control the dimensions of the subplots as in my dummy example in the beginning of this post). It is important for me to adjust the image size to the size of the page.
I would also like to know how to use a namespace qualifier while calling patchwork in the working example, so I would not call a function from another package by an accident.
I followed the instructions from these sources:
https://ggplot2-book.org/arranging-plots.html
https://patchwork.data-imaginist.com/articles/guides/layout.html - (footnote: I do not understand the textual representation of layout)
Combine multiple patchworks
One option would be to use the design argument to specify the layout:
library(ggplot2)
library(patchwork)
design = "
CD
AA
BB
"
plot1 + plot2 + plot3 + plot4 +
plot_layout(
design = design,
heights = c(2, 4, 7))

ggplot2, introduce breaks on a x log scale

I have a plot like this:
p<-ggplot() +
geom_line(data= myData, aes(x = myData$x , y = myData$y)) +
scale_x_log10()+
scale_y_log10()
My x value is seq(9880000, 12220000, 10000)
There is only one break on the x-axis of the plot, what should I do if to get at least 3 breaks on the plot x-axis?
Here is fully reproducible example of the original poster's problem where a log-scaled plot only displays one break value on the x-axis. I demonstrate three possible solutions below.
library(ggplot2)
# Create a reproducible example data.frame using R functions.
x = seq(9880000, 12220000, 10000)
# Use set.seed() so that anyone who runs this code
# will get the same sequence of 'random' values.
set.seed(31415)
y = cumsum(runif(n=length(x), min=-1e5, max=1e5)) + 1e6
dat = data.frame(x=x, y=y)
# Original poster's plot.
p1 = ggplot(data=dat, aes(x=x, y=y)) +
geom_line() +
scale_x_log10() +
scale_y_log10() +
labs(title="1. Plot has only one x-axis break.")
# Add extra x-axis breaks manually.
x_breaks = c(10^7.0, 10^7.04, 10^7.08)
p2 = ggplot(data=dat, aes(x=x, y=y)) +
geom_line() +
scale_x_log10(breaks=x_breaks) +
scale_y_log10() +
labs(title="2. Add some x-axis breaks manually.")
# Add extra x-axis breaks in semi-automated manner.
x_breaks = 10^pretty(log10(x))
x_labels = formatC(x_breaks, format = "e", digits = 2)
p3 = ggplot(data=dat, aes(x=x, y=y)) +
geom_line() +
scale_x_log10(breaks=x_breaks, labels=x_labels) +
scale_y_log10() +
labs(title="3. Create x-axis breaks with R functions.")
# Skip the log10 scale because the x-values don't span multiple orders of magnitude.
p4 = ggplot(data=dat, aes(x=x, y=y)) +
geom_line() +
scale_y_log10() +
labs(title="4. Check appearance without log10 scale for x-axis.")
library(gridExtra)
ggsave("example.png", plot=arrangeGrob(p1, p2, p3, p4, nrow=2),
width=10, height=5, dpi=150)
I add: scale_x_log10(breaks=seq(9880000, 12220000, 1000000)).
This is my reproducible example:
library(random)
library(ggplot2)
z <- randomStrings(n=235, len=5, digits=TRUE, upperalpha=TRUE, loweralpha=TRUE, unique=TRUE, check=TRUE)
x <- seq(9880000, 12220000, 10000)
y <- randomNumbers(n=235, min=9880000, max=12220000, col=1)
df <- data.frame(z, x, y)
head(df)
V1 x V1.1
1 378VO 9880000 11501626
2 AStRK 9890000 10929705
3 sotp4 9900000 11305700
4 AS4DR 9910000 11302110
5 7iFdk 9920000 11611918
6 HIS7z 9930000 11175074
p<-ggplot() + geom_line(data= df, aes(x = df$x , y = df$V1.1)) + scale_y_log10()
p + scale_x_log10(breaks=seq(9880000, 12220000, 1000000))
Hope it is useful...
Add this between your parenthesis: breaks=seq(specify, breaks, here)
For example, if you wanted a break at 0, 10, 100:
scale_x_log10((breaks=seq(0,10,100))

How to center x axis labels on the y = 0 axis with ggplot2?

I have the following R code:
library("ggplot2")
x=read.table('some_file')
df <- data.frame(V1 = x$V1, V2 = x$V2)
jpeg('file.jpg',width=1600,height=800)
ggplot(df, aes(x=as.numeric(row.names(df)), y=V1)) +
geom_bar(stat="identity", fill="grey", width=0.7) +
geom_errorbar(aes(ymin = V1 - V2, ymax = V1 + V2), width=0.5) +
scale_x_continuous(breaks=c(1,seq(1,length(x$V1),1)), expand=c(0,0)) +
theme(axis.text.x=element_text(size = 9, angle = 90, vjust = 0.5, hjust=8.5)) + xlab("position") + ylab("Y axis") + labs(title = "Title")
dev.off
I need the x axis labels, i.e., the numbers 1,2,3... to lie on the y = 0 axis or just below it. I tried playing around with hjust, but no matter what value I used for it, it didn't work quite right. For example, with hjust=8.5 the numbers from 100 to 167 are where I need them to be, but the numbers before that are too much above the y = 0 axis.
Can anybody help? Here are the two column vectors in question:
-0.11285825 0.0134043866
-0.00427275 0.0012140211
-0.00825875 0.0025256419
-0.08434275 0.0153227983
0.111627 0.0149667631
-0.00591775 0.0028993564
-0.00710475 0.0014442042
-0.00660175 0.0005508105
0.1259935 0.0176350505
-0.02468425 0.0049306177
-0.0046885 0.0005749567
-0.002225 0.0009090044
-0.01276025 0.0040398386
-0.11821675 0.0699125335
-0.0035805 0.0010421268
-0.00276825 0.0011773666
-0.014487 0.0004579208
-0.06269425 0.0181558159
-0.0028185 0.0004570594
0.00163075 0.0004970686
-0.003703 0.0005301641
-0.0059895 0.00101644
-0.00164725 0.0005756263
-0.001748 0.0008530894
-0.00265675 0.0001855982
0.0617135 0.0148209217
-0.20685225 0.0116178605
0.001209 0.0015875276
-0.000297 0.0006022711
0.00447675 0.0012625121
-0.00088225 0.0040488959
-0.1444145 0.0142768668
-0.01167825 0.0012083802
0.01813575 0.0031464967
-0.007798 0.0106417775
-0.18151 0.0073565153
0.36773125 0.0181246164
0.562059 0.1015533768
-0.00886525 0.0131807785
0.174133 0.0431058507
0.57896425 0.2444875207
-0.8418545 0.138881625
0.02951775 0.0654937622
-0.12007175 0.034225026
-1.6405275 0.5553336954
-1.88679875 0.7850254112
-0.231041 0.0164808312
-0.1266595 0.0617940077
-0.19167575 0.0507706792
-1.055467 0.4429050182
-0.116364 0.0357189981
-0.19901725 0.0509971349
-1.7670315 0.1542821762
-0.10039375 0.0352431413
-0.11883575 0.0114192525
-0.3665885 0.1246847809
-1.9132725 0.5623975368
-0.31451275 0.1145112995
-0.11942425 0.0375176069
-0.04436425 0.0204052159
-0.0098315 0.0023110857
-0.007022 0.0030733554
-0.1755365 0.1161738267
-0.081695 0.0216418659
-0.06446825 0.006684648
-0.5098405 0.5403101751
-0.05826375 0.1454962774
-0.28179575 0.0358286362
-0.201353 0.0584529251
-0.7666615 0.143889849
-3.36481375 0.2914767538
-0.358104 0.0669525527
-0.17513975 0.0110406376
-3.76037275 0.7028178063
-2.91671325 0.0631300928
-0.382157 0.0164434459
0.28983275 0.1447389319
-0.1522485 0.6711400536
-0.21333325 0.0195889096
-0.135311 0.019034877
-2.54135775 0.1089711993
-1.02318925 0.096562207
-1.52091 0.1405089663
-9.649117 0.2311164764
-0.36733 0.0339848999
-0.89744525 0.0296846006
-0.69533325 0.0863715014
-0.30171975 0.0261684616
-0.0915285 0.0101355205
0.11442675 0.0466793911
-1.05659675 0.1963164192
-0.01967525 0.0056679875
0.00163325 0.0047527004
-0.008276 0.035198076
-0.070888 0.0277879036
0.0003515 0.0048609681
-0.00769575 0.0051084448
-0.0628 0.0277348014
-0.00517225 0.0050401386
-0.002678 0.0015185852
0.000215 0.0106790497
0.0303 0.0148194041
0.0157995 0.0098726426
-0.01274725 0.0026780256
-0.00394375 0.0006370312
0.00103025 0.0003137287
-0.00834475 0.0004048057
-0.010351 0.0012089266
-0.00144675 0.0003594665
-0.019411 0.0143840738
-0.01995875 0.0014986806
-0.00944875 0.0008936362
-0.00012 0.0001115437
-0.017019 0.0007678965
-0.0146025 0.0058825609
-0.00330075 0.000519175
0.0034255 0.001374384
-0.03580625 0.0039048393
-0.0008405 0.0010331095
0.006152 0.000903144
0.08482425 0.0169920168
0.013677 0.0030233132
-0.00002725 0.0015909331
0.15528725 0.0129757832
0.0062995 0.000357788
-0.0886525 0.0078460151
0.01510875 0.0010974966
0.00863325 0.0004734867
0.32934625 0.0152748957
0.067786 0.0029502796
0.00300625 0.0004219979
0.04193375 0.0018489418
-0.0000245 0.009160398
0.3010235 0.0192036334
-0.01484775 0.0286606604
-0.183226 0.050428693
-0.026292 0.005153877
0.53286075 0.050951844
-1.5150745 0.2209543557
0.2785605 0.0408203229
0.4550995 0.027406819
-0.3947985 0.4327885451
0.23381825 0.2238431016
-0.22846625 0.0188915484
-0.31804825 0.2029861787
-1.7850215 0.5281493487
-1.67640075 0.2481773479
-0.661103 0.0595275708
-4.67910175 1.0021441745
-0.22585775 0.2284251402
0.4079195 0.2637898013
-0.82208 0.1246448589
-3.8169575 0.2426232257
-5.66482025 0.5167259264
-0.65876175 0.1498171905
-3.275229 0.4303526931
-0.80324675 0.11413495
-2.2098325 0.1510774807
-0.8855575 0.6300580366
-4.4606575 0.2082186001
0.95024225 0.1393782289
-0.26379 0.0212151113
-0.436935 0.1433744083
-2.34355175 0.0412962458
0.60204025 0.0836441211
-0.16453425 0.0148762548
0.4368215 0.1924153651
Manual placement will give you full control. Also, x is already a data.frame read.table() produces data.frames.
library(ggplot2)
df <- read.table('somefile')
jpeg('file.jpg',width=1600,height=800)
gg <- ggplot(df, aes(x=as.numeric(row.names(df)), y=V1))
gg <- gg + geom_bar(stat="identity", fill="grey", width=0.7)
gg <- gg + geom_errorbar(aes(ymin = V1 - V2, ymax = V1 + V2), width=0.5)
gg <- gg + geom_text(data=data.frame(x=1:length(df$V1)),
aes(x=x, y=0, label=x), size=2.5, angle=90, hjust=0)
gg <- gg + scale_x_continuous(expand=c(0,0))
gg <- gg + labs(x="position", y="Y axis", title="Title")
gg <- gg + theme(axis.ticks.x=element_blank())
gg <- gg + theme(axis.text.x=element_blank())
gg
dev.off()
system("open file.jpg")

Varying factor order in each facet of ggplot2

I am trying to create a Cleveland Dot Plot given for two categories in this case J and K. The problem is the elements A,B,C are in both categories so R keeps farting. I have made a simple example:
x <- c(LETTERS[1:10],LETTERS[1:3],LETTERS[11:17])
type <- c(rep("J",10),rep("K",10))
y <- rnorm(n=20,10,2)
data <- data.frame(x,y,type)
data
data$type <- as.factor(data$type)
nameorder <- data$x[order(data$type,data$y)]
data$x <- factor(data$x,levels=nameorder)
ggplot(data, aes(x=y, y=x)) +
geom_segment(aes(yend=x), xend=0, colour="grey50") +
geom_point(size=3, aes(colour=type)) +
scale_colour_brewer(palette="Set1", limits=c("J","K"), guide=FALSE) +
theme_bw() +
theme(panel.grid.major.y = element_blank()) +
facet_grid(type ~ ., scales="free_y", space="free_y")
Ideally, I would want a dot plot for both categories(J,K) individually with each factor(vector x) decreasing with respect to the y vector. What ends up happening is that both categories aren't going from biggest to smallest and are erratic at the end instead. Please help!
Unfortunately factors can only have one set of levels. The only way i've found to do this is actually to create two separate data.frames from your data and re-level the factor in each. For example
data <- data.frame(
x = c(LETTERS[1:10],LETTERS[1:3],LETTERS[11:17]),
y = rnorm(n=20,10,2),
type= c(rep("J",10),rep("K",10))
)
data$type <- as.factor(data$type)
J<-subset(data, type=="J")
J$x <- reorder(J$x, J$y, max)
K<-subset(data, type=="K")
K$x <- reorder(K$x, K$y, max)
Now we can plot them with
ggplot(mapping = aes(x=y, y=x, xend=0, yend=x)) +
geom_segment(data=J, colour="grey50") +
geom_point(data=J, size=3, aes(colour=type)) +
geom_segment(data=K, colour="grey50") +
geom_point(data=K, size=3, aes(colour=type)) +
theme_bw() +
theme(panel.grid.major.y = element_blank()) +
facet_grid(type ~ ., scales="free_y", space="free_y")
which results in

Display two parallel axes on a ggplot (R)

Let's say we have a simple plot of the following kind.
library(ggplot2)
df = data.frame(y=c(0,1.1,2.3,3.1,2.9,5.8,6,7.4,8.2,9.1),x=seq(1,100, length.out=10))
ggplot(df,aes(x=x,y=y)) + geom_point()
x perfectly correlates with z. The relation is: Constant=x^2*z=1.23
therefore I could rewrite the data.frame like this:
df = cbind(df,1.23/df$x^2)
The question is:
How can I display both variables xand zone the x-axis? It could be one at the bottom and one at the top of the graph or both at the bottom.
Here's a dangerous attempt. Previous version with a log-scale was just wrong.
library(ggplot2)
df = data.frame(y=c(0,1.1,2.3,3.1,2.9,5.8,6,7.4,8.2,9.1),
x=seq(1,100, length.out=10))
df$z = 1.23/df$x^2
## let's at least remove the gridlines
p1 <- ggplot(df,aes(x=x,y=y)) + geom_point() +
scale_x_continuous(expand=c(0,0)) +
theme(panel.grid.major=element_blank(),
panel.grid.minor = element_blank())
## make sure both plots have expand = c(0,0)
## otherwise data and top-axis won't necessarily be aligned...
p2 <- ggplot(df,aes(x=z,y=y)) + geom_point() +
scale_x_continuous(expand=c(0,0))
library(gtable)
g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(p2)
tmp <- gtable_filter(g2, pattern="axis-b")
## ugly tricks to extract and reshape the axis
axis <- tmp[["grobs"]][[1]][["children"]][["axis"]] # corrupt the children
axis$layout <- axis$layout[2:1,]
axis$grobs[[1]][["y"]] <- axis$grobs[[1]][["y"]] - unit(1,"npc") + unit(0.15,"cm")
## back to "normality"
g1 <- gtable_add_rows(g1, sum(tmp$heights), 2)
gtableAddGrobs <- gtable_add_grob # alias, making sure #!hadley doesn't see this
g1 <- gtableAddGrobs(g1,
grobs=list(gtable_filter(g2, pattern="xlab"),axis),
t=c(1,3), l=4)
grid.newpage()
grid.draw(g1)
A both-on-the-bottom approach can be done with the excellent cowplot library.
library(ggplot2)
library(cowplot)
data <- data.frame(temp_c=runif(100, min=-5, max=30), outcome=runif(100))
plot <- ggplot(data) +
geom_point(aes(x=temp_c, y=outcome)) +
theme_classic() +
labs(x='Temperature (Celsius)')
x2plot <- ggplot(data) +
geom_point(aes(x=temp_c, y=outcome)) +
theme_classic() +
scale_x_continuous(label=function(x){round(x*(9/5) + 32)}) +
labs(x='Temperature (Fahrenehit)')
x <- get_x_axis(x2plot)
xl <- get_plot_component(x2plot, "xlab-b")
plot_grid(plot, ggdraw(x), ggdraw(xl), align='v', axis='rl', ncol=1,
rel_heights=c(0.8, 0.05, 0.05))

Resources