davidcarslaw / openair

Tools for air quality data analysis
https://davidcarslaw.github.io/openair/
GNU General Public License v2.0
302 stars 113 forks source link

timePlot or scatterPlot : Is a second y-axis possible? #12

Open MatthiasKetzel opened 9 years ago

MatthiasKetzel commented 9 years ago

Is there a possibility on R or openAir to add a secondary y-axis in a plot and having data using either primary or secondary y-axis?

I am aware of the normalise and group options in timePlot that could be used for this. Just sometimes it would be good to have two axis that you can control and scale separately.

davidcarslaw commented 9 years ago

Many argue against second y-axes as being potentially misleading - better to normalise the data. However, I think this can be useful in some situations. I will have a look at the work involved as I am keen to keep the functions relatively simple.

lyggd commented 7 years ago

Is there anyone know how to a second y-axis ? Thanks !

romainderain commented 6 years ago

Hello !

So there are an answer to draw a second y-axis ??

Romain

nogpaul commented 3 years ago

adding second y axis will have been very useful for cluster analysis. for example for the analysis of vertical course of the trajectories with cluster data. (x-axis time increment, y-axis left water vapor, y-axis right pressure.)identify sink / source along the respective cluster trajectory. if there is a way around this please help. currently I am trying to achieve this with matlab

Thanks @davidcarslaw @jobonaf @GjjvdBurg @cvitolo @Agriculturist

nogpaul commented 3 years ago

Many argue against second y-axes as being potentially misleading - better to normalise the data. However, I think this can be useful in some situations. I will have a look at the work involved as I am keen to keep the functions relatively simple.

So how can I normalise the data for something like this; After clustering using this function clust <- trajCluster(method, method = "Angle", n.cluster = 6, col = "Set2", map.cols = openColours("Paired", 10),) I want to plot, vertical course of the trajectories with cluster data. (x-axis time increment, y-axis left water vapor, y-axis right pressure.)identify sink / source along the respective cluster trajectory. I have tried this function trendLevel( clust, pollutant = "qvapor", x = "hour", y = "pressure",type = "cluster") but I wanted qvapor to be the second y axis, but currently I am just using it as pollutant, which is not what is needed. So how can I normalize data? @davidcarslaw

schonhose commented 3 years ago

It would really help if we would have some example data, and an example of the figure you are trying to achieve with your current R-code.

jack-davison commented 1 year ago

I'll keep this open for now, however - broadly speaking - there's a lot of reasons why secondary y axes are a bad idea, and commonly there are less misleading data visualisation strategies.

If you are really keen on a secondary y axis, you could look to use ggplot2, although its authors also warn against using secondary axes.

library(openair)
library(tidyverse)
#> Warning: package 'ggplot2' was built under R version 4.2.2
#> Warning: package 'purrr' was built under R version 4.2.2
#> Warning: package 'dplyr' was built under R version 4.2.2
#> Warning: package 'stringr' was built under R version 4.2.2
#> Warning: package 'forcats' was built under R version 4.2.2

data <- smoothTrend(mydata, c("nox", "no2"), plot = FALSE)$data

# shift secondary pollutant to be on a similar scale
data$data <- data$data %>%
  mutate(
    conc = if_else(variable == "no2", conc * 5, conc),
    variable = case_match(variable, "no2" ~ "NO<sub>2</sub>", "nox" ~ "NO<sub>x</sub>")
  )

data$fit <- data$fit %>%
  mutate(pred = if_else(variable == "no2", pred * 5, pred),
         lower = if_else(variable == "no2", lower * 5, lower),
         upper = if_else(variable == "no2", upper * 5, upper),
         variable = case_match(variable, "no2" ~ "NO<sub>2</sub>", "nox" ~ "NO<sub>x</sub>"))

# make ggplot2
ggplot(mapping = aes(x = date)) +
  geom_point(data = data$data, aes(y = conc, color = variable)) +
  geom_line(data = data$data, aes(y = conc, color = variable)) +
  geom_line(data = data$fit, aes(y = pred, color = variable)) +
  geom_ribbon(data = data$fit,
              aes(ymax = upper, ymin = lower, fill = variable),
              alpha = .5) +
  scale_y_continuous(name = quickText("NOx (ug/m3)"), # shift secondary axis back by the same factor
                     sec.axis = sec_axis(~ . / 5, name = quickText("NO2 (ug/m3)"))) +
  theme_bw() +
  theme(legend.text = ggtext::element_markdown())

Created on 2023-02-08 with reprex v2.0.2