2

I am creating a graph divided into facets. Some of these facets need to be on a smaller scale for better viewing. I have already applied several tricks to achieve this. However, I need to change the limits and divisions of the axes of some facets.

Calling the necessary packages, creating the database and making the plot

devtools::install_github("zeehio/facetscales")
library(ggplot2)
library(facetscales)

#Constructing data frame
Source <- c(rep("Water", 12), rep("Oil", 12))
Range <- rep((c(rep("First", 4), rep("Second", 8))),2)
Xaxis <- c(0,1,2,5,0,1,2,5,10,20,30,40,
           0,1,2,5,0,1,2,5,10,20,30,40)
Yaxis <- c(0,1,2,5,0,1,2,5,10,20,30,40,
           0,1,2,5,0,1,2,5,10,20,30,40)

DF <- data.frame(Source, Range, Xaxis, Yaxis)
      
#plot
p <- ggplot(data = DF, aes(x = Xaxis, y = Yaxis)) +
  geom_smooth(method = "lm",
              formula = y ~ x) +
  geom_point()

I initially used facet_wrap with scales = "free", but what I really want is to be able to modify the limits and divisions of the x-axis of the facets in the "First" row.

#plot using facet wrap
p + facet_wrap(Range~Source,
               scales = "free") +
  ggtitle("Using facet_wrap")

enter image description here

So I chose to use the facetscales package and followed this (1) and this (2) examples

#axis specifications
scale_x <- list(
  "First" = scale_x_continuous(limits = c(0, 10), breaks = c(0, 2, 10)),
  "Second"= scale_x_continuous(limits = c(0, 40), breaks = c(0, 5, 40))
)

#plot using facet grid and the facetscales package
p + facet_grid_sc(rows = vars(Range),
                  cols = vars (Source),
                  scales = list(x = scale_x)) +
  ggtitle("Using facet_grid_sc")

When trying to make the graph with the specifications that I need appears:

error in x$clone() attempt to apply non-function

I don't understand what I'm doing wrong. Could someone help me, please?

Daniel Valencia C.
  • 2,159
  • 2
  • 19
  • 38
  • 1
    its hard to say, maybe `facetscales` depends on an older version of the `ggplot2` package? `ggplot2::Scale` is the only `ggproto` object that has a `$clone()` method. If `facetscales` replaces the `scales` object with something that doesn't have a `$clone()` method then thats the issue. – Justin Landis Mar 16 '21 at 19:00
  • 1
    Also, I checked, it does have a `$clone()` method, so this may just be a bug. Maybe post about it on the developer's github? – Justin Landis Mar 16 '21 at 19:32

1 Answers1

1

I think I found the reason it doesn't work,

in facet_grid the scales parameter was used to indicate if each panel would have similar or different scales with c("free","free_x","free_y"). But having free_x on facet_grid is only free in the horizontal direction, and all vertical groupings have the same scale range.

When specifying facet_grid_sc, the scales parameter is used to distinguish how each scale will be rendered, specifically scales = list(x = scale_x) where scale_x matches cols = vars(Range)

library(ggplot2)
library(facetscales)

#Constructing data frame
Source <- c(rep("Water", 12), rep("Oil", 12))
Range <- rep((c(rep("First", 4), rep("Second", 8))),2)
Xaxis <- c(0,1,2,5,0,1,2,5,10,20,30,40,
           0,1,2,5,0,1,2,5,10,20,30,40)
Yaxis <- c(0,1,2,5,0,1,2,5,10,20,30,40,
           0,1,2,5,0,1,2,5,10,20,30,40)

DF <- data.frame(Source, Range, Xaxis, Yaxis)

p <- ggplot(data = DF, aes(x = Xaxis, y = Yaxis)) +
  geom_smooth(method = "lm",
              formula = y ~ x) +
  geom_point()

#old plot without facet_grid_sc
p + facet_grid(rows = vars(Range),
               cols = vars (Source))

You see how if you facet by Range on rows, they are split vertically instead of horizontality? I dont think facet_grid_sc supports a free_x while also specifiying the x element of scales

scale_x <- list(
  First = scale_x_continuous(limits = c(0, 10), breaks = c(0, 2, 10)),
  Second= scale_x_continuous(limits = c(0, 40), breaks = c(0, 5, 40))
)

#new plot where scale_x matches cols argument
p + facet_grid_sc(cols = vars(Range),
                  rows = vars (Source),
                  scales = list(x = scale_x))

Created on 2021-03-16 by the reprex package (v1.0.0)


EDIT

It should be noted that facet_grid_sc is probably more useful if you want to control the range or labels of each panel cols/rows individually. Using scales = "free_x" in facet_grid is actually pretty sufficient in this example.


p + facet_grid(cols = vars(Range),
               rows = vars (Source),
               scales = "free_x")

Created on 2021-03-16 by the reprex package (v1.0.0)

Justin Landis
  • 1,981
  • 7
  • 9