I have this plot and I need to round the y axis so what appears is acceptable EXCEPT for the fact that I would like to not just show 1 value on the y axis. I'd like to add the "limit" to the "scale_y_continuous" function so that the limits for each facet plot are unique to the individual facet.
here is the plot only showing 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 add the limit in the scale y continuous and it applies the limit globally.
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 to each facet plot so something like
so the right plot would have limits of
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 limit of
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 the limits be adjusted to be specific to the individual facet plots?
To change the axis scales on a plot in base R Language, we can use the xlim() and ylim() functions. The xlim() and ylim() functions are convenience functions that set the limit of the x-axis and y-axis respectively.
While facet_grid shows the labels at the margins of the facet plot, facet_wrap creates a label for each plot panel.
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 use data.table by = group
to create y_min
and y_max
for each group. And then use those values in geom_blank
to extend the plot area.
Obviously, this is automatically scalable to any number of groups/facets.
One option is to make each of the facets separately, and then stitch them back together. This has the added benefit that you can use something other than 10 for your break sequencing (e.g., if one of your groups spans from 100 to 1000, you could use 200 instead with a little tinkering).
First, I am creating a function to calculate the breaks. (This is the function that you would modify 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 make a plot from the 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)
})
Note that I still used facet_wrap
in order to get the strip
-style title above the plot, though you could just use ggtitle
instead if you like that styling better.
Then, use plot_grid
from cowplot
to stitch everything back together. Do note that if you load cowplot
it sets it's own default theme. To revert back, use theme_set(theme_gray())
cowplot::plot_grid(plotlist = sepPlots)
gives
cowplot
is pretty well documented, so you should be able to make adjustments to the plot as needed when you scale up to more groups.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With