How to set limits on the rounded face of the wrapper y?

I have this graph, and I need to surround the y axis, so what seems acceptable is EXCEPT that I would like to not just show 1 value along the y axis. I would like to add a “limit” to the “scale_y_continuous” function so that the limits for each facet plot are unique to a single face.

here the graph shows only 60 and 80 on the y axis

dat = data.frame(x = c(1,2,3,1,2,3),A=c(80.6, 82,83,60,61,62),A_up =c(81,84,85,62,63,64), A_low =c(79,78,81,59,58,57), group = c("z","z","z","y","y","y")) ggplot(data=dat , aes(x=as.factor(x), y=A, group = 1)) + #, color =Group, group = Group geom_line() + geom_point() + # facet_wrap(~COUNTERPARTY_STRATEGY ,ncol=2) geom_errorbar(aes(ymax = A_up ,ymin = A_low), width = .25) + scale_y_continuous(breaks = seq( floor( (min(dat$A_low)-11) /10)*10 , ceiling( (max(dat$A_up)+11) /10)*10,10 ), labels = seq( floor( (min(dat$A_low)-11) /10)*10 , ceiling( (max(dat$A_up)+11) /10)*10,10 ) ) + facet_wrap(~group ,ncol=2, scales = "free_y") 

Now I am adding the y-scale limit to continuous, and it applies the limit all over the world.

 dat = data.frame(x = c(1,2,3,1,2,3),A=c(80.6, 82,83,60,61,62),A_up =c(81,84,85,62,63,64), A_low =c(79,78,81,59,58,57), group = c("z","z","z","y","y","y")) ggplot(data=dat , aes(x=as.factor(x), y=A, group = 1)) + #, color =Group, group = Group geom_line() + geom_point() + # facet_wrap(~COUNTERPARTY_STRATEGY ,ncol=2) geom_errorbar(aes(ymax = A_up ,ymin = A_low), width = .25) + scale_y_continuous(breaks = seq( floor( (min(dat$A_low)-11) /10)*10 , ceiling( (max(dat$A_up)+11) /10)*10,10 ), labels = seq( floor( (min(dat$A_low)-11) /10)*10 , ceiling( (max(dat$A_up)+11) /10)*10,10 ), # limits = c( floor( min(dat$A_low[dat$group =="z"]) /10)*10 ,ceiling(max(dat$A_up[dat$group =="z"])/10)*10 ) #limits = c( floor( min(dat$A_low[dat$group =="z"]) /10)*10 ,ceiling(max(dat$A_up[dat$group =="z"])/10)*10 ) limits = c( floor( min(dat$A_low) /10)*10 ,ceiling(max(dat$A_up)/10)*10 ) ) + facet_wrap(~group ,ncol=2, scales = "free_y") 

i.e.

c( floor( min(dat$A_low) /10)*10 ,ceiling(max(dat$A_up)/10)*10 )

is 50 and 90

but I would like the limit to be unique for each facet plot, so something like

so the right stretch will have limits

c( floor( min(dat$A_low[dat$group =="y"]) /10)*10 ,ceiling(max(dat$A_up[dat$group =="y"])/10)*10 )

50 and 70

and the left plot would have a limit

c( floor( min(dat$A_low[dat$group =="z"]) /10)*10 ,ceiling(max(dat$A_up[dat$group =="z"])/10)*10 )

70 and 90

How can limits be adjusted to be specific for individual face plots?

+7
r ggplot2 facet
source share
3 answers
 dat = data.frame(x = c(1,2,3,1,2,3),A=c(80.6, 82,83,60,61,62),A_up =c(81,84,85,62,63,64), A_low =c(79,78,81,59,58,57), group = c("z","z","z","y","y","y")) dat <- data.table(dat) dat[, y_min := floor( min(A_low) /10)*10, by = group] dat[, y_max := ceiling(max(A_up)/10)*10 , by = group] ggplot(data=dat , aes(x=as.factor(x), y=A, group = 1)) + #, color =Group, group = Group geom_line() + geom_point() + # facet_wrap(~COUNTERPARTY_STRATEGY ,ncol=2) geom_errorbar(aes(ymax = A_up ,ymin = A_low), width = .25) + scale_y_continuous(breaks = seq( floor( (min(dat$A_low)-11) /10)*10 , ceiling( (max(dat$A_up)+11) /10)*10,10 ), labels = seq( floor( (min(dat$A_low)-11) /10)*10 , ceiling( (max(dat$A_up)+11) /10)*10,10 ) ) + facet_wrap(~group ,ncol=2, scales = "free_y") + geom_blank(aes(y = y_min)) + geom_blank(aes(y = y_max)) 

So here I am using data.table by = group to create y_min and y_max for each group. And then use these values ​​in geom_blank to expand the plot area.

enter image description here

Obviously, this automatically scales to any number of groups / faces.

+6
source share

One option is to make each of the faces separately, and then stitch them together. This has the added benefit that you can use something other than 10 for your interrupt sequence (for example, if one of your groups spans from 100 to 1000, you can use 200 instead with a small wizard).

First, I create a function to compute gaps. (This is a function that you would change if you want different scales for different ranges.)

 myBreaks <- function(x){ seq(floor( (min(x) ) /10)*10 , ceiling( (max(x) ) /10)*10, 10 ) } 

Then use lapply to create a graph from a subset of your data for each group:

 sepPlots <- lapply(levels(dat$group), function(thisGroup){ ggplot(data= dat[dat$group == thisGroup, ], aes(x=as.factor(x), y=A, group = 1)) + geom_line() + geom_point() + geom_errorbar(aes(ymax = A_up ,ymin = A_low), width = .25) + scale_y_continuous(breaks = myBreaks, limits = range(myBreaks(dat[dat$group == thisGroup, c("A_up", "A_low")])) ) + facet_wrap(~group) }) 

Notice that I still used facet_wrap to get the strip header over the plot, although you can just use ggtitle if you like this style better.

Then use plot_grid from cowplot to stitch everything together. Please note that if you download cowplot , it sets its own theme by default. To go back, use theme_set(theme_gray())

 cowplot::plot_grid(plotlist = sepPlots) 

gives

enter image description here

cowplot is well documented, so you should make adjustments to the schedule as needed when you scale to more groups.

+2
source share

I don't have ggplot, but maybe a simple if () else can solve your problem. My first attempt would be this:

 if { (dat$group =="y") c( floor( min(dat$A_low[dat$group =="y"]) /10)*10, ceiling(max(dat$A_up[dat$group =="y"])/10)*10 ) else c( floor( min(dat$A_low[dat$group =="z"]) /10)*10, ceiling(max(dat$A_up[dat$group =="z"])/10)*10 ) } 
-4
source share

All Articles