how to set limits on rounded facet wrap y axis?

旧街凉风 提交于 2019-11-29 14:37:29

问题


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?


回答1:


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.




回答2:


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.




回答3:


I don't have ggplot installed, but maybe a simple if () else could 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 )
}


来源:https://stackoverflow.com/questions/40137060/how-to-set-limits-on-rounded-facet-wrap-y-axis

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!