ggplot2 cuts off parts of my figure when zooming in - r

I am trying to make a figure in gglot2 that looks something like this.
However, I seem right now to have a trade off between having all the squares small like ... Or zooming in on the squares and having parts cut
both displayed here as I may not add more pictures, yet
My code is as follow
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')
Odds <- c(1.2,1,0.97,1,1.38,0.95,0.85,0.95)
x <- c(5,3.5,0,-3.5,-5,-3.5,0,3.5)
y <- c(0,3.5,5,3.5,0,-3.5,-5,-3.5)
summed <- data.frame(Odds,x,y)
d <- qplot(x, y, data=summed, colour =Odds)
d + theme_classic(base_size = 14) + geom_point(size = 30, shape=15) +
scale_colour_gradient(low="grey", high = "black") +
ylab("") +
xlab("") +
scale_y_continuous(breaks=NULL) + scale_x_continuous(breaks=NULL)
I hope some of you can help me.

GGplot grants a certain "bleeding" or "breathing" around plot area. The size of your geom_point simply goes beyond that space.
A solution is to set custom limits to the ploting area. Try this:
d <-qplot(x, y, data=summed, color =Odds)
d + theme_classic(base_size = 14) + geom_point(size = 30, shape=15) +
scale_colour_gradient(low="grey", high = "black") +
ylab("") +
xlab("") +
scale_y_continuous(breaks=NULL) +
scale_x_continuous(breaks=NULL) +
theme(aspect.ratio = 1) + ## Optional. Ensures you get a square shaped plot
expand_limits(x =c(min(x) - 1, max(x) + 1), ## Expands the limits, reads from your predefined "x" and "y" objects.
y =c(min(y)-1, max(y) +1))

Related

Issue with log_2 scaling using ggplot2 and log2_trans()

I am trying to plot data using ggplot2 in R.
The datapoints occur for each 2^i-th x-value (4, 8, 16, 32,...). For that reason, I want to scale my x-Axis by log_2 so that my datapoints are spread out evenly. Currently most of the datapoints are clustered on the left side, making my plot hard to read (see first image).
I used the following command to get this image:
ggplot(summary, aes(x=xData, y=yData, colour=groups)) +
geom_errorbar(aes(ymin=yData-se, ymax=yData+se), width=2000, position=pd) +
geom_line(position=pd) +
geom_point(size=3, position=pd)
However trying to scale my x-axis with log2_trans yields the second image, which is not what I expected and does not follow my data.
Code used:
ggplot(summary, aes(x=settings.numPoints, y=benchmark.costs.average, colour=solver.name)) +
geom_errorbar(aes(ymin=benchmark.costs.average-se, ymax=benchmark.costs.average+se), width=2000, position=pd) +
geom_line(position=pd) +
geom_point(size=3, position=pd) +
scale_x_continuous(trans = log2_trans(),
breaks = trans_breaks("log2", function(x) 2^x),
labels = trans_format("log2", math_format(2^.x)))
Using scale_x_continuous(trans = log2_trans()) only doesn't help either.
EDIT:
Attached the data for reproducing the results:
https://pastebin.com/N1W0z11x
EDIT 2:
I have used the function pd <- position_dodge(1000) to avoid overlapping of my error bars, which caused the problem.
Removing the position=pd statements solved the issue
Here is a way you could format your x-axis:
# Generate dummy data
x <- 2^seq(1, 10)
df <- data.frame(
x = c(x, x, x),
y = c(0.5*x, x, 1.5*x),
z = rep(letters[seq_len(3)], each = length(x))
)
The plot of this would look like this:
ggplot(df, aes(x, y, colour = z)) +
geom_point() +
geom_line()
Adjusting the x-axis would work like so:
ggplot(df, aes(x, y, colour = z)) +
geom_point() +
geom_line() +
scale_x_continuous(
trans = "log2",
labels = scales::math_format(2^.x, format = log2)
)
The labels argument is just so you have labels in the format 2^x, you could change that to whatever you like.
I have used the function pd <- position_dodge(1000) to avoid overlapping of my error bars, which caused the problem.
Adjusting the amount of position dodge and the with of the error bars according to the new scaling solved the problem.
pd <- position_dodge(0.2) # move them .2 to the left and right
ggplot(summary, aes(x=settings.numPoints, y=benchmark.costs.average, colour=algorithm)) +
geom_errorbar(aes(ymin=benchmark.costs.average-se, ymax=benchmark.costs.average+se), width=0.4, position=pd) +
geom_line(position=pd) +
geom_point(size=3, position=pd) +
scale_x_continuous(
trans = "log2",
labels = scales::math_format(2^.x, format = log2)
)
Adding scale_y_continuous(trans="log2") yields the results I was looking for:

Viridis and ggplot2/ggmarginal

I am encountering a problem using viridis with ggplot2 and ggmarginal.
I would like to colorize dots on a Bland-Altman Plot that I am plotting with ggplot2:
diff <- (a1$A1_phones - a1$A1_video)
diffp <- (a1$A1_phones - a1$A1_video)/a1$A1_video*100
sd.diff <- sd(diff)
sd.diffp <- sd(diffp)
my.data <- data.frame(a1$A1_video, a1$A1_phones, diff, diffp)
dev.off()
diffplot <- ggplot(my.data, aes(a1$A1_video, diff)) +
geom_point(size=2, colour = rgb(0,0,0, alpha = 0.5)) +
theme_bw() +
#when the +/- 2SD lines will fall outside the default plot limits
#Thanks to commenter for noticing this.
ylim(mean(my.data$diff) - 7*sd.diff, mean(my.data$diff) + 7*sd.diff) +
geom_hline(yintercept = 0, linetype = 3) +
geom_hline(yintercept = mean(my.data$diff)) +
geom_hline(yintercept = mean(my.data$diff) + 2*sd.diff, linetype = 2) +
geom_hline(yintercept = mean(my.data$diff) - 2*sd.diff, linetype = 2) +
ylab("Difference Video vs Algorithm [ms]") +
xlab("Average of Video vs Algorithm [ms]")
p<-ggMarginal(diffplot, type="histogram", bins = 40)+ scale_colour_viridis_d()
It would now be very beautiful to colorize the dots from A1_video differently than those from A1_phones and have viridis drawing a continuous density plot.
I am not sure if this is what you want, please try to be more specific and provide sample data. If you just want the color to change based on another column in the source dataset , it must be specified inside the aes() function:
diffplot <- ggplot(my.data,aes(col=a1$A1_video))

How can I align a map plot and a boxplot that share a y-axis

I am trying to align or combine a map and a boxplot, both of which have latitude as their y-axis. I've found a number of ways to align plots, but it seems like having a map involved complicates things. I'd like to have the two plots align seamlessly, with the map on the left and boxplot on the right.
Here's example code for the two plots:
library(ggplot2)
library(maps)
library(gridExtra)
##Plot base map
s_map <- map_data('state',region=c('south carolina','georgia','florida'))
p <- ggplot() + coord_fixed()
base_world <- p+geom_polygon(data=s_map, aes(x=long, y=lat, group=group), color="white", fill="grey72")
yscale <- c(24:34)
map1 <- base_world +
coord_map(xlim = c(-83, -79.5),ylim = c(25, 34)) +
xlab("") +
ylab("Latitude") +
scale_y_discrete(labels=yscale)
##plot boxplot (seasonal movements of an animal)
df <- data.frame("month"=month.abb,
"min"=c(26,26,26,28,28,29,29,29,28,28,26,26),
"lci"=c(27,27,27,29,29,30,30,30,29,29,27,27),
"med"=c(28,28,28,29,29,31,31,31,29,29,28,28),
"uci"=c(29,29,29,30,30,32,32,32,30,30,29,29),
"max"=c(30,30,30,31,31,33,33,33,31,31,30,30),
"order"=c(1:12))
boxplot1 <- ggplot(df, aes(x=factor(order), ymin = min, lower = lci, middle = med, upper = uci, ymax = max)) +
geom_boxplot(stat = "identity") +
ggtitle("Latitude by Month") +
xlab("Month") +
ylab("Latitude") +
ylim(24,33)
grid.arrange(map1,boxplot1,ncol=2)
How do I force the y-axes and plot heights to be the same, with gridlines aligned?
Thanks in advance for your thoughts on this - I'm still pretty new with R.
EDITED:
I've tried probably a dozen fragments of code I found, and nothing much seemed effective at all, so I didn't think listing them would be helpful. I'm mostly looking for a real place to start.
Here's one example I found for forcing plot heights to be the same, but it didn't seem to do anything:
# build the plots
map2 <- ggplot_gtable(ggplot_build(map1))
boxplot2 <- ggplot_gtable(ggplot_build(boxplot1))
# copy the plot height from p1 to p2
boxplot2$heights <- map2
grid.arrange(map2,boxplot2,ncol=2,widths=c(1,5))
This might work for you, I changed three things:
added ggtitle("") to the map
added theme(plot.margin()) to both plots to change the space around the plots (you can play with the values)
added scale_y_continuous(limits=c(24,33), breaks=seq(24,33,by=1), expand=c(0,0)) to the plot in order to create same axis scale as for the map
map1 <- base_world +
coord_map(xlim = c(-83, -79.5),ylim = c(25, 34)) +
xlab("") +
ylab("Latitude") +
scale_y_discrete(labels=yscale) +
ggtitle("") +
theme(plot.margin=unit(c(0.5,-1.5,0.5,-8), "cm"))
boxplot1 <- ggplot(df, aes(x=factor(order), ymin = min, lower = lci, middle = med, upper = uci, ymax = max)) +
geom_boxplot(stat = "identity") +
ggtitle("Latitude by Month") +
xlab("Month") +
ylab("Latitude") +
scale_y_continuous(limits=c(24,33), breaks=seq(24,33,by=1), expand=c(0,0)) +
labs(y=NULL) +
theme(plot.margin=unit(c(0.5,0.5,0.5,-6), "cm"))
grid.arrange(map1,boxplot1,ncol=2)

Change size of a line plot, understand how the size argument works

I'm making a multiple lines plot with errorbars. If I don't use the size argument, everything is fine:
# sample data
Response=runif(4)
ResponseMin=Response-Response/5
ResponseMax=Response+Response/5
Cases=rep(c("Case1","Case2"),each=2)
df=data.frame(x=1:2,Average=Response,Lower=ResponseMin,Upper=ResponseMax,Case=Cases)
# let's plot
library(ggplot2)
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25)) +
labs(y="foo",title="Some plot fu")
However, when I modify the line size, I start getting weird stuff:
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case, size = 1)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25)) +
labs(y="foo",title="Some plot fu")
Why the extra legend entry "1"? And when I add a size argument for the errobars, it looks like the size of the lines stays the same, whatever the value of size is:
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case, size = 1)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25, size = 1)) +
labs(y="foo",title="Some plot fu")
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case, size = 2)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25, size = 2)) +
labs(y="foo",title="Some plot fu")
Can you help me figure out what's happening here?
If you set size inside aes you are mapping it to a variable
`1` = 1
and ggplot2 creates a legend. If you just want to set the size, you can do that outside of aes:
geom_line(aes(group=Case), size = 1)
try this, size outside aes()
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case), size = 1) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25)) +
labs(y="foo",title="Some plot fu")

Error bars show through open symbol

I have a plot with pairs of points that are slightly offset. Each pair of points has associated error bars. I have specified that the symbol of the first point in the pair is different from that of the second (closed circle vs open circle). I would like it so that the error bars do not show through the open symbol.
Here is a mock data set:
x = runif(4,-2,2)
x_1 = runif(4,-1,3)
dfr <- data.frame(
x = c(x, x_1),
y = rep(c("A","B","C","D"), 2),
upper = c(x+2, x_1+1),
lower = c(x-2, x_1-2),
type = rep(c("alpha", "beta"), each = 4))
And here is the plot:
dodge=position_dodge(width=0.5)
ggplot(dfr,aes(x=y,y=x,colour=type)) +
geom_point(size=8,aes(shape=type),position=dodge) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
scale_colour_manual(values = c('gray','black')) +
scale_shape_manual(values = c(19,21)) +
coord_flip() +
opts(legend.position="none")
Thanks for any help you can provide!
I can't think of a way to make an 'open' point and not let the errorbar show trough. The only way of doing this would be to fill the points with the same colour as the background, but then your gridlines won't be visible through the point.
To do this, map the fill aesthetic to type, and specify scale_fill_manual with the fill colour grey90 which is the theme_grey setting:
ggplot(dfr,aes(x=y,y=x,colour=type, fill=type)) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
geom_point(size=8,aes(shape=type),position=dodge) +
scale_colour_manual(values = c('gray','black')) +
scale_fill_manual(values=c('grey', 'grey90')) +
scale_shape_manual(values = c(19,21)) +
coord_flip() +
opts(legend.position="none")
Why don't you just use color as shown in the modified code below. It will fill the black circles too. Not sure if that is acceptable.
ggplot(dfr,aes(x=y,y=x,colour=type)) +
geom_point(size=8,position=dodge) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
scale_colour_manual(values = c('gray','black')) +
coord_flip() +
opts(legend.position="none")

Resources