Why is sec_axis behaving strangely when used in combination with patchwork?

28 views Asked by At

EDIT: I just looked closer and it turns out that the values for the y axis ticks are not off by simple multiples of 25 and 50. Instead, it turns out that the function will always use the final value for the second y axis factor (i.e. the one for Nigeria), for all the plots. It seems to want to use this value regardless of what the value of secondyaxisfactor is in the point in the code where it is actually supposed to calculate the axis values (which I have verified using diagnostic prints).

I'm still at a loss as to why this is happening or how to stop it.


I am trying to use the patchwork package to create three plots with identical aesthetics, to display pipeline construction data for three countries. I have the price of oil and gas plotted on a separate y axis, normalized to each fuel's price in 2020 to enable easy comparisons.

The data already includes a column which calculates the adjusted price data, by multiplying it by a different multiplier for each country, which is based on the maximum pipeline construction per year for the country. It also includes a column listing said maximum.

The plots are made using a for loop. At the start of the loop, I calculate certain parameters for each plot based on the country whose data it displays. This includes the variable secondyaxis factor: The number by which the first y axis must be divided to get an accurate scale on the secondary y axis.

The relevant code is pasted below.

I have quadruple-checked that secondyaxis factor is being calculated correctly, which it is. However, the plot just won't adjust the axis correctly. Here is one of the plots I created:

enter image description here

Even weirder: It always adjusts the axis correctly on the final plot it makes. The first plot is off by a factor of 50, and the second by a factor of 25. So there is clearly a pattern, but I can't figure out what is going on.

Does anybody have any ideas? This is driving me kind of nuts.

CODE: (I know aspects of this are extremely janky. I'm a relative R novice who picks up new techniques and approaches as I need them for my job. Please be gentle. I've removed a few irrelevant lines to make it easier to follow)

`plotslist <- NULL
    for (i in countries){
      subplotname <- make.names(
        paste("p",
              i,
              sep = ".")
      )
      plotslist <- c(plotslist,
                     subplotname)
      countryplotdata <- filter(FIG.A.plotdata,
                                Country == i)
      
      price.2020 <- countryplotdata$Price.
      secondyaxisfactor <- 1/(countryplotdata$Country.Max[1]/4)
      
      
      p1 <- ggplot(filter(countryplotdata,
                         !is.na(Fuel)
                         )
                  )
      
      if (plotform == "Line") {
        p1 <- p1 + geom_line(aes(x = Year,
                               y = Length,
                               col = Fuel))
      }
      else if (plotform == "Column"){
        p1 <- p1 + geom_col(aes(x = Year,
                              y = Length,
                              fill = Fuel),
                          position = "Dodge")
      }
      
      if (includeprice == TRUE){
        p1 <- p1 +
          geom_line(aes(x = Year,
                        y = Price.Converted,
                        col = Price.Time.Series)
          ) +
          scale_y_continuous(name = yname,
                             sec.axis = sec_axis( ~ . * secondyaxisfactor)
          )
      }
      
      else {
        p1 <- p1 +
          scale_y_continuous(name = yname)
      }
      
      p1 <- p1 +
        scale_x_continuous(limits = xlimits,
                           breaks = plotbreaks) +
        theme(legend.position = "none",
              axis.title.x = element_blank(),
              axis.text.x = element_blank(),
              axis.ticks.x = element_blank(),
              axis.title.y = element_text(size = 10),
              strip.text = element_text(face = "bold"),
              plot.margin = unit(rep(0,4),
                                 "cm"))
}

}`

I have tried verifying that secondyaxis factor is being calculated correctly, in several ways. I printed it out in several points in the code, and have saved the final data frame being used for each subplot to the global environment right before the lines that plot the price time series so that I can look at it in detail. It is correct every time.

I expected the plot's second y axis to have the value of 1, at each of the points where the red and blue lines meet (because the time series data is normalized to that date). Instead, it is 25 in the second plot and 50 in the first.

0

There are 0 answers