When I run this code:
ggplot() +
stat_density2d(data = Unit_J, aes(x=X, y=Y, fill=..level.., alpha=0.9), lwd= 0.05, bins=50, col="blue", geom="polygon") +
scale_fill_continuous(low="blue",high="darkblue") +
scale_alpha(range=c(0, 0.03), guide="none") +
xlim(-6600,-3800) + ylim(400,2500) +
coord_fixed(expand=FALSE) +
geom_point(data = Unit_J, aes(x=X, y=Y), alpha=0.5, cex=0.4, col="darkblue") +
theme_bw() +
theme(legend.position="none")
I get this plot:
I know that increasing in this case X lims would solve the problem of unclosed lines shown on the left and right.
However, I want to keep these limits unchanged so that those "bugs" don't appear, and simply they must be beyond the limits, somehow hidden without creating those horrible lines.
Is there any possibility?
EDIT (download data here):
In order to ease and reproduce the example, you can download the data here
The trick is to expand the canvas using xlim and ylim so that there is enough room for ggplot to draw complete contours around the data. Then you can use tighter xlim and ylim parameters within the coord_fixed term to show the window you want...
ggplot() +
stat_density2d(data = Unit_J, aes(x=X, y=Y, fill=..level.., alpha=0.9),
lwd= 0.05, bins=50, col="blue", geom="polygon") +
scale_fill_continuous(low="blue",high="darkblue") +
scale_alpha(range=c(0, 0.03), guide="none") +
xlim(-7000,-3500) + ylim(400,2500) + #expanded in x direction
coord_fixed(expand=FALSE,xlim=c(-6600,-3800),ylim=c(400,2500)) + #added parameters
geom_point(data = Unit_J, aes(x=X, y=Y), alpha=0.5, cex=0.4, col="darkblue") +
theme_bw() +
theme(legend.position="none")
Related
I am creating a point plot and I wanted to add a bar to the bottom of a point plot. I can't seem to find out how to do this in the ggplot documentation. I was hoping to add at bar the spanned the entire x-axis with a set y-axis value. Here is an example of the data I am working with
d=data.frame(drink=c("coffee","tea","water"), mean=c(5,6,9), lower=c(4.5,5.6,8.7), upper=c(5.5,6.3,9.5))
and here is the code I am using
ggplot() +
geom_errorbar(data=d, mapping=aes(x=drink, ymin=upper, ymax=lower), width=0.2, size=1, color="blue") +
geom_point(data=d, mapping=aes(x=drink, y=mean), size=4, shape=21, fill="white") +
scale_y_continuous(n.breaks = 10) + ylim(0, 12)
Here is what the plot currently looks like
and this is what I want to add
The annotate() function allows you to directly specify a layer without intermediate data.frame. In ggplot2, the -Inf/Inf values for continuous variables indicate to place something at the extremes.
library(ggplot2)
d=data.frame(drink=c("coffee","tea","water"),
mean=c(5,6,9),
lower=c(4.5,5.6,8.7),
upper=c(5.5,6.3,9.5))
ggplot(d) +
geom_errorbar(
mapping=aes(x=drink, ymin=upper, ymax=lower),
width=0.2, size=1, color="blue") +
geom_point(
mapping=aes(x=drink, y=mean),
size=4, shape=21, fill="white") +
scale_y_continuous(n.breaks = 10, limits = c(0, 12)) +
annotate("rect", xmin = -Inf, xmax = Inf,
ymin = -Inf, ymax = 1, fill = "black")
Created on 2021-09-13 by the reprex package (v2.0.1)
I have made a bar graph and would like it to have a log-scaled y axis. However, when I try to add the code for this, it for some reason inverses most of the bars... Can anyone explain why this may be and how to remedy this?
The code I use is as follows:
Graph1 <- ggplot(Data, aes(x=Temp, y=Mean, fill=Exposure)) +
geom_bar(position=position_dodge(), stat='identity', color="black",) +
xlab("Temperature (°C)") +
ylab("Cd concentration (µg/g)") +
facet_wrap(.~Day, scales="free_y", labeller=labeller(Day=supp.labsDAY), nrow = 1, ncol = 4)+
geom_errorbar( aes(x=Temp, ymin=Mean-SEM, ymax=Mean+SEM), width = 0.2, position=position_dodge(.9))
Graph1+ scale_y_log10()
I have a grid of plots, all with the same y and x-axis scale. The plots represent time in the x-axe and mean values in the y-axe with their standard errors. My problem is that some errorbars are not entirely within the plot margins, and I wonder if there is some way to represent the part of the errorlines that are within the plot margins. Below I give a fake example and code to play with:
df <- data.frame(time=seq(-15,15,1),
mean=c(0.49,0.5,0.53,0.55,0.57,0.59,0.61,0.63,0.65,0.67,0.69,0.71,0.73,0.75,0.77,0.79,0.77,0.75,0.73,0.71,0.69,0.67,0.65,0.63,0.61,0.59,0.57,0.55,0.53,0.51,0.49),
sd=c(0.09,0.087,0.082,0.08,0.023,0.011,0.010,0.009,0.008,0.007,0.006,0.005,0.004,0.003,0.002,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.010,0.011,0.023,0.08,0.084,0.087,0.09))
Plot <- ggplot(df, aes(x=time, y=mean)) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), width=.3) +
geom_point(size=1) +
geom_line () +
theme_bw() +
scale_y_continuous(limits = c(0.49, 0.85), breaks = c(0.5, 0.65,0.8))
Plot
You need to set coord_cartesian limits rather than scale_y_continuous limits:
ggplot(df, aes(x=time, y=mean)) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), width=.3) +
geom_point(size=1) +
geom_line () +
theme_bw() +
scale_y_continuous(breaks = c(0.5, 0.65,0.8)) +
coord_cartesian(ylim = c(0.49, 0.85))
I have some data where x is categorical, y is numeric, and color.var is another categorical variable that I would like to color by. My goal is to plot all of the points using position_jitterdodge(), and then highlight a couple of the points, draw a line between them, and add labels, while making sure these highlighted points line up with the corresponding strips of points that were plotted using position_jitterdodge(). The highlighted points are aligned properly when all factors are present in the variable used to dodge, but it does not work well when some factors are missing.
Minimal (non-)working example
library(ggplot2)
Generate some data
d = data.frame(x = c(rep('x1', 1000), rep('x2', 1000)),
y = runif(n=2000, min=0, max=1),
color.var= rep(c('color1', 'color2'), 1000),
facet.var = rep(c('facet1', 'facet1', 'facet2', 'facet2'), 500))
head(d)
dd = d[c(1,2,3,4,1997,1998, 1999,2000),]
dd
df1 = dd[dd$color.var=='color1',] ## data for first set of points, labels, and the line connecting them
df2 = dd[dd$color.var=='color2',] ## data for second set of points, labels, and the line connecting them
df1
dw = .75 ## Define the dodge.width
Plot all points
Here are all of the points, separated using position_jitterdodge() and the aesthetic fill.
ggplot() +
geom_point(data=d, aes(x=x, y=y, fill=color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
theme(axis.title = element_blank()) +
theme(legend.position="top")
That works well.
Additional highlighted points.
Here is the same plot, with additional points in dd added.
ggplot() +
geom_point(data=d, aes(x=x, y=y, fill =color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
geom_point(data=dd, aes(x=x, y=y, color=color.var ), position=position_dodge(width=.75), size=4 ) +
geom_line(data=dd, aes(x=x, y=y, color=color.var, group=color.var ), position=position_dodge(width=.75), size=1 ) +
geom_label(data=dd, aes(x=x, y=y, color=color.var, group=color.var, label=round(y,1)), position=position_dodge(width=.75), vjust=-.5) +
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
scale_color_manual(values=c( 'blue', 'gray40')) +
theme(axis.title = element_blank())+
theme(legend.position="top")
This is what I want it to look like. However, this only works properly if both factors of the color.var variable are in the set of points to highlight.
If both factors aren't present in the new data, the horizonal alignment fails.
Highlight points, only one factor present
Here is an example where only the 'color1' factor (blue) is present. Note that data=dd was replaced with data=df1 (data that only contains blue highlighted dots) in this code.
ggplot() +
geom_point(data=d, aes(x=x, y=y, fill =color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
geom_point(data=df1, aes(x=x, y=y, color=color.var ), position=position_dodge(width=.75), size=4 ) +
geom_line(data=df1, aes(x=x, y=y, color=color.var, group=color.var ), position=position_dodge(width=.75), size=1 ) +
geom_label(data=df1, aes(x=x, y=y, color=color.var, group=color.var, label=round(y,1)), position=position_dodge(width=.75), vjust=-.5) +
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
scale_color_manual(values=c( 'blue', 'gray40')) +
theme(axis.title = element_blank())+
theme(legend.position="top") +
scale_x_discrete(drop=F)
The highlight blue dots appear between the blue and gray dots, instead of aligned with the blue dots. Note that the additional code scale_x_discrete(drop=F) had no apparent effect on the alignment.
A manual solution
One possible fix is to edit the x coordinate manually, like this
ggplot(data=d, aes(x=x, y=y)) +
geom_point(aes(fill=color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
geom_point(data=df1, aes(x=as.numeric(x)-dw/4, y=y), alpha=.9, size=4 , color='blue') + ## first set of points
geom_line( data=df1, aes(x=as.numeric(x)-dw/4, y=y , group=color.var ), color='blue', size=1) + ## first line
geom_label(data=df1, aes(x=as.numeric(x)-dw/4, y=y , label=round(y,1)), color='blue', vjust=-.25)+ ## first set of labels
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
theme(axis.title = element_blank() +
theme(legend.position="top")
An adjustment of 1/4 of the dodge.width seems to work. This works fine, but it seems like there should be a better way, especially since I will eventually want to do this with 4-5 sets of highlighted points/lines, which may all be all be the same color.var, like the blue 'color1' factor above. Repeating this 4-5 times would be cumbersome. I will also eventually want to do this will 5-10 different figures. I suppose dodge.width*1/4 will always work, and copying and pasting might do the trick, but would like to know if there is a better way.
Here is a solution based on #aosmith's comment. Basically, just need to add this code before using ggplot:
library(dplyr) ## needed for group_by()
library(tidyr) ## needed for complete()
df1 = df1 %>% group_by(facet.var, x) %>% complete(color.var)
That adds extra rows to the data so that all the levels of color.var are present. Then the code given in the question, along with a couple of small edits that fix the legend, can be used:
ggplot() +
geom_point(data=d , aes(x=x, y=y, fill =color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray', show.legend=T) +
geom_point(data=df1, aes(x=x, y=y, color=color.var ), position=position_dodge(width=.75), size=4, show.legend=T ) +
geom_line( data=df1, aes(x=x, y=y, color=color.var, group=color.var ), position=position_dodge(width=.75), size=1, show.legend=F ) +
geom_label(data=df1, aes(x=x, y=y, color=color.var, group=color.var, label=round(y,1)), position=position_dodge(width=.75), vjust=-.5, show.legend=F) +
facet_wrap(~facet.var) +
scale_fill_manual( values=c( 'lightblue','gray'), name='Background dots', guide=guide_legend(override.aes = list(color=c('lightblue', 'gray')))) +
scale_color_manual(values=c( 'blue', 'gray40') , name='Highlighted dots') +
theme(axis.title = element_blank())+
theme(legend.position="top")+
scale_x_discrete(drop=F)
In a ggplot boxplot, it is easy to use jitter to add the raw data points with varying degrees of jitter. With zero jitter the following code
dat <- data.frame(group=c('a', 'b', 'c'), values = runif(90))
ggplot(dat, aes(group, values)) +
geom_boxplot(outlier.size = 0) +
geom_jitter(position=position_jitter(width=0), aes(colour=group), alpha=0.7) +
ylim(0, 1) + stat_summary(fun.y=mean, shape=3, col='red', geom='point') +
opts(legend.position = "right") + ylab("values") + xlab("group")
produces the plot below.
Is it possible to use zero jitter but add an offset such that the points are in a line but shifted left by 25% of the box width? I tried geom_point with dodge but this generated a jitter.
If we convert group to numeric and then add an offset, you seem to get your desired output. There is probably a more effective / efficient way, but give this a whirl:
ggplot(dat, aes(group, values)) +
geom_boxplot(outlier.size = 0) +
geom_point(aes(x = as.numeric(group) + .25, colour=group), alpha=0.7) +
ylim(0, 1) + stat_summary(fun.y=mean, shape=3, col='red', geom='point') +
opts(legend.position = "right") + ylab("values") + xlab("group")