Skip to contents

There are three plot types built into mqor(). To demonstrate them, we first need to calculate some statistics to use as inputs.

stats_long <- summarise_mqo_stats(demo_longterm, "PM10", term = "long")

stats_short <- summarise_mqo_stats(demo_shortterm, "PM10", term = "short")

Plot Types

‘Comparison’ Bars

To visualise measurement data directly, it can be useful to start with plot_comparison_bars().

For long-term data, this draws a bar chart of both observed and modelled values, with an ‘acceptability range’ (AR) drawn for the observation bars. Modelled values meeting MQI[long] <= 1 for a particular sampling point are within the corresponding observed value’s AR.

Long term comparison bars

For short-term data, plot_comparison_bars() shows RMSE & RMSU*[0] (RMSU multiplied by the square root of 1 + beta squared).

Short term comparison bars

You will likely notice that both statistics objecst are fed into the same function; the function is intelligent enough to understand if the stats are for short- or long-term data, and choose appropriate statsitics to visualise.

Model Quality Bars

To actually apply the MQO, plot_mqi_bars() will create an ordered bar chart showing the MQI for each sampling point. The dashed horizontal line shows the MQI[90th]. These plots are very similar regardless of whether the short- or long-term statistics are of interest.

plot_mqi_bars(stats_long)

Long term MQI bars

plot_mqi_bars(stats_short)

Long term MQI bars

Model Quality Scatter

For large numbers of sites, a complementary ‘scatter’ chart can be useful as a bar chart will grow more crowded.

For long-term data, plot_mqi_scatter() shows a scatter of modelled and observed concentrations, with the AR as a shaded area.

plot_mqi_scatter(stats_longterm = stats_long)

Long term MQI scatter

For short-term data, plot_mqi_scatter() shows a special ‘target’ diagram. If both sets of stats are provided, the target diagram also labels MQI long.

plot_mqi_scatter(stats_shortterm = stats_short, stats_longterm = stats_long)

Short term MQI scatter

These plots vary somewhat for ‘mixed’ networks of both fixed and indicative sites, incorporating colour to show both acceptability ranges on one plot.

demo_longterm |>
  dplyr::mutate(
    type = c(rep("fixed", 10), rep("indicative", 5))
  ) |>
  summarise_mqo_stats("PM10") |>
  (\(x) plot_mqi_scatter(stats_longterm = x))()
#> ! term assumed to be 'long'.
#>  If this is incorrect, please specify the data's term using the term argument.

Short term MQI scatter for a mixed network

demo_shortterm |>
  dplyr::mutate(
    type = c(rep("fixed", 50), rep("indicative", 25))
  ) |>
  summarise_mqo_stats("PM10") |>
  (\(x) plot_mqi_scatter(stats_shortterm = x))()
#> ! term assumed to be 'short'.
#>  If this is incorrect, please specify the data's term using the term argument.

Short term MQI scatter for a mixed network

Model Quality Report

Both short- and long-term statistics can be viewed simultaneously in the MQI “report” format, which shows both the short- and long-term MQI as well as all complementary indicators. Much like the MQI scatter plots, this plot distinguishes between fixed and indicative sites.

plot_mqi_report(stats_shortterm = stats_short, stats_longterm = stats_long)

An MQI 'report' plot, showing horizontal bars displaying performance indicators in both time and space.

Customisation

Users have some basic control over the colours used in each plot. These arguments always start with color_ and take either R colour names or hex codes.

plot_comparison_bars(
  stats_long,
  color_mod = "#003776",
  color_obs = "#F8AE21",
  color_outline = "#404040"
)

A bar chart with blue, yellow and grey colours instead of grey and black.

The static plots are built using ggplot2, a highly capable and customisable plotting language. A particular strength of ggplot2 is its allowance for post-hoc customisations. If you aren’t familiar with ggplot2, please refer to https://ggplot2-book.org/ for guidance from its authors. The below code chunk demonstrates a few options available to users, including changing the plot theme, axis scales, annotations, and so on.

plot_comparison_bars(stats_short, color_outline = "white") +
  # add a new theme
  ggplot2::theme_dark() +
  ggplot2::theme(legend.position = "bottom") +
  # change labels
  ggplot2::labs(x = "Monitoring Sites", fill = "Statistic") +
  # change y scale
  ggplot2::scale_y_continuous(limits = c(0, 40)) +
  # add an annotation
  ggplot2::annotate(
    x = "S11",
    y = 20,
    geom = "text",
    color = "white",
    label = "Look\nat this!"
  ) +
  ggplot2::annotate(
    x = "S11",
    xend = "S11",
    y = 17.5,
    yend = 14,
    geom = "segment",
    color = "white",
    arrow = ggplot2::arrow(length = ggplot2::unit(0.25, "cm"))
  )
#> Scale for y is already present.
#> Adding another scale for y, which will replace the existing scale.

A mqor plot customised using ggplot2.

For complete customisation, users are naturally free to re-plot the summary statistics in any way they find useful. ggplot2 is a good candidate for this, but users can choose to use base R plotting, a different plotting library, a JavaScript wrapper like plotly or echarts4r, or even export the statistics tables for use in other software like Excel or Python.

library(ggplot2)

summarise_mqo_stats(demo_shortterm, pollutant = "PM10")$by_site |>
  ggplot(aes(x = mean_obs, y = mean_mod)) +
  geom_smooth(method = "lm") +
  geom_pointrange(aes(ymin = mean_mod - sd_mod, ymax = mean_mod + sd_mod), alpha = 0.5) +
  geom_pointrange(aes(xmin = mean_obs - sd_obs, xmax = mean_obs + sd_obs), alpha = 0.5) +
  coord_fixed() +
  theme_bw() +
  labs(
    x = "Observed Values",
    y = "Modelled Values"
  )
#> ! term assumed to be 'short'.
#>  If this is incorrect, please specify the data's term using the term argument.
#> `geom_smooth()` using formula = 'y ~ x'

A manually constructed ggplot2 plot using mqor statistics.

Dynamic Plots

Each of the plotting functions has an interactive argument. When TRUE, the JavaScript library plotly is used to produce a dynamic chart. These outputs are naturally inappropriate to include in a typical PDF report, but are better suited for web applications, Quarto or rmarkdown dynamic reports, or exploratory analysis.

plot_comparison_bars(stats_long, interactive = TRUE)
plot_mqi_bars(stats_long, interactive = TRUE)
plot_mqi_scatter(stats_longterm = stats_long, interactive = TRUE)
plot_mqi_scatter(stats_shortterm = stats_short, stats_longterm = stats_long, interactive = TRUE)
plot_mqi_report(stats_short, stats_long, interactive = TRUE)