# Simplevis

    library(dplyr)
    library(simplevis)

### Purpose

simplevis is a package of wrapper functions to make ggplot2 and leaflet visualisation easier.

The aim is of simplevis is to make the majority of visualisations easier, while supporting users to move between ggplot2 and simplevis as needed.

simplevis makes things easier by:

- minimising visualisation types available to vbar, hbar, point, line, boxplot or sf
- minimising aesthetics available to x, y, colour and facetting
- using a simpler method for colouring
- using consistent prefixes and the Rstudio auto-complete function
- using ggplot2 based terminology for leaflet visualisation.

The package also supports making mobile-friendly visualisation for mobile devices.

### Overview

`simplevis` provides the following families of ggplot2 visualisation:

Graph:

- horizontal bar (`ggplot_hbar`)
- vertical bar (`ggplot_vbar`)
- line plot (`ggplot_line`)
- scatter graph (`ggplot_point`)
- boxplot (`ggplot_boxplot`)

Map:

- sf (`ggplot_sf`)

Each visualisation family has a family of generally 4 functions.

The function name specifies whether or not a ggplot is to be coloured by a variable, facetted by a variable, or neither or both of these. Colouring by a variable means that different values of a selected variable are to have different colours. Facetting means different values of a selected variable are to have there own mini-plot, and these are to be placed alongside each other.

Each ggplot2 wrapper family follows the structure as below:

- `ggplot_hbar()`: a horizontal bar graph.
- `ggplot_hbar_col()`: a horizontal bar graph that is coloured by a variable.
- `ggplot_hbar_facet()`: a facetted horizontal bar graph.
- `ggplot_hbar_col_facet()`a facetted horizontal bar graph that is coloured by a variable.

For different types of graph, just replace `ggplot_hbar` with `ggplot_line`, `ggplot_point`, `ggplot_vbar`, `ggplot_boxplot` or `ggplot_sf`.

In general, required arguments (i.e. specifications) to functions are:

- `data`
- `x_var` (not required for `sf`)
- `y_var` (not required for `sf`)

If you are using a `_col` or `_col_facet` function:

- `col_var`

If you are using a `_facet` or `_col_facet` function:

- `facet_var`

It is always recommended to add a `title`, `x_title` and `y_title` too.

### Plots not coloured by a variable.

Identify the function that you need, then provide the `data`, an `x_var` and a `y_var` (unless of the `ggplot_sf` family).

    plot_data <- ggplot2::diamonds %>%
      slice_sample(prop = 0.05) %>%
      tibble::as_tibble()

    plot_data
    #> # A tibble: 2,697 x 10
    #>    carat cut       color clarity depth table price     x     y     z
    #>    <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
    #>  1  0.84 Fair      G     VS1      55.6    64  2724  6.42  6.32  3.54
    #>  2  0.3  Premium   I     VVS1     61.2    60   709  4.29  4.27  2.62
    #>  3  0.24 Very Good F     VVS1     60.6    60   478  4.03  4.06  2.45
    #>  4  1.01 Ideal     E     SI1      62      57  5235  6.38  6.45  3.98
    #>  5  0.9  Ideal     H     VS1      60.9    57  4201  6.2   6.24  3.79
    #>  6  1.02 Very Good F     IF       62.5    58 10967  6.39  6.54  4.04
    #>  7  0.31 Ideal     G     VS2      61.4    57   698  4.37  4.33  2.67
    #>  8  1.3  Premium   F     SI2      61.1    58  6261  7.02  6.98  4.28
    #>  9  0.55 Ideal     G     VS1      62.2    54  2132  5.27  5.24  3.27
    #> 10  0.64 Premium   D     VS2      60.9    59  2243  5.6   5.63  3.42
    #> # … with 2,687 more rows

    ggplot_point(plot_data, carat, price)

    plot_data <- ggplot2::diamonds %>%
      group_by(cut) %>%
      summarise(average_price = mean(price)) %>%
      mutate(average_price = average_price / 1000) %>%
      mutate(cut = stringr::str_to_sentence(cut)) %>%
      tibble::as_tibble()

    plot_data
    #> # A tibble: 5 x 2
    #>   cut       average_price
    #>   <chr>             <dbl>
    #> 1 Fair               4.36
    #> 2 Good               3.93
    #> 3 Very good          3.98
    #> 4 Premium            4.58
    #> 5 Ideal              3.46

    ggplot_hbar(plot_data,
                x_var = average_price,
                y_var = cut,
                title = "Average diamond price by cut",
                x_title = "Average price ($US thousands)",
                y_title = "Cut")

    plot_data <- storms %>%
      group_by(year) %>%
      summarise(average_wind = mean(wind)) %>%
      tibble::as_tibble()

    plot_data
    #> # A tibble: 41 x 2
    #>     year average_wind
    #>    <dbl>        <dbl>
    #>  1  1975         50.9
    #>  2  1976         59.9
    #>  3  1977         54.0
    #>  4  1978         40.5
    #>  5  1979         48.7
    #>  6  1980         53.7
    #>  7  1981         56.6
    #>  8  1982         49.5
    #>  9  1983         47.0
    #> 10  1984         51.4
    #> # … with 31 more rows

    ggplot_vbar(plot_data,
                x_var = year,
                y_var = average_wind)

    plot_data <- storms %>%
      group_by(year) %>%
      summarise(wind = mean(wind)) %>%
      tibble::as_tibble()

    plot_data
    #> # A tibble: 41 x 2
    #>     year  wind
    #>    <dbl> <dbl>
    #>  1  1975  50.9
    #>  2  1976  59.9
    #>  3  1977  54.0
    #>  4  1978  40.5
    #>  5  1979  48.7
    #>  6  1980  53.7
    #>  7  1981  56.6
    #>  8  1982  49.5
    #>  9  1983  47.0
    #> 10  1984  51.4
    #> # … with 31 more rows

    ggplot_line(plot_data,
                x_var = year,
                y_var = wind)

Note the `ggplot_boxplot` functions transform the data to boxplot statistics by default.

    plot_data <- iris %>%
      mutate(Species = stringr::str_to_sentence(Species)) %>%
      tibble::as_tibble()

    plot_data
    #> # A tibble: 150 x 5
    #>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #>           <dbl>       <dbl>        <dbl>       <dbl> <chr>
    #>  1          5.1         3.5          1.4         0.2 Setosa
    #>  2          4.9         3            1.4         0.2 Setosa
    #>  3          4.7         3.2          1.3         0.2 Setosa
    #>  4          4.6         3.1          1.5         0.2 Setosa
    #>  5          5           3.6          1.4         0.2 Setosa
    #>  6          5.4         3.9          1.7         0.4 Setosa
    #>  7          4.6         3.4          1.4         0.3 Setosa
    #>  8          5           3.4          1.5         0.2 Setosa
    #>  9          4.4         2.9          1.4         0.2 Setosa
    #> 10          4.9         3.1          1.5         0.1 Setosa
    #> # … with 140 more rows

    ggplot_boxplot(plot_data,
                   x_var = Species,
                   y_var = Petal.Length)

### Plots coloured by a variable

To colour by a variable, use a `_col` function (e.g. `ggplot_hbar_col`). Add a `col_var` variable in addition.

    plot_data <- ggplot2::diamonds %>%
      group_by(cut, clarity) %>%
      summarise(average_price = mean(price)) %>%
      mutate(average_price = average_price / 1000) %>%
      mutate(cut = stringr::str_to_sentence(cut)) %>%
      tibble::as_tibble()

    plot_data
    #> # A tibble: 40 x 3
    #>    cut   clarity average_price
    #>    <chr> <ord>           <dbl>
    #>  1 Fair  I1               3.70
    #>  2 Fair  SI2              5.17
    #>  3 Fair  SI1              4.21
    #>  4 Fair  VS2              4.17
    #>  5 Fair  VS1              4.17
    #>  6 Fair  VVS2             3.35
    #>  7 Fair  VVS1             3.87
    #>  8 Fair  IF               1.91
    #>  9 Good  I1               3.60
    #> 10 Good  SI2              4.58
    #> # … with 30 more rows

    ggplot_hbar_col(plot_data,
                    x_var = average_price,
                    y_var = cut,
                    col_var = clarity)

### Plots facetted by a variable

To facet by a variable, use a `_facet` function.

    plot_data <- ggplot2::diamonds %>%
      mutate(cut = stringr::str_to_sentence(cut)) %>%
      group_by(cut, clarity) %>%
      summarise(average_price = mean(price)) %>%
      mutate(average_price = average_price / 1000) %>%
      tibble::as_tibble()

    plot_data
    #> # A tibble: 40 x 3
    #>    cut   clarity average_price
    #>    <chr> <ord>           <dbl>
    #>  1 Fair  I1               3.70
    #>  2 Fair  SI2              5.17
    #>  3 Fair  SI1              4.21
    #>  4 Fair  VS2              4.17
    #>  5 Fair  VS1              4.17
    #>  6 Fair  VVS2             3.35
    #>  7 Fair  VVS1             3.87
    #>  8 Fair  IF               1.91
    #>  9 Good  I1               3.60
    #> 10 Good  SI2              4.58
    #> # … with 30 more rows

    ggplot_hbar_facet(plot_data,
                      x_var = average_price,
                      y_var = cut,
                      facet_var = clarity)

### Plots coloured by a variable and facetted by a variable

facet by a variable, use a `_col_facet` function.

    plot_data <- ggplot2::diamonds %>%
      mutate(cut = stringr::str_to_sentence(cut)) %>%
      group_by(cut, clarity, color) %>%
      summarise(average_price = mean(price)) %>%
      mutate(average_price = round(average_price / 1000, 1))

    ggplot_hbar_col_facet(plot_data,
                          x_var = average_price,
                          y_var = color,
                          col_var = clarity,
                          facet_var = cut)

### `sf` ggplot maps

`simplevis` provides simple feature (`sf`) maps (i.e. maps with point, line or polygon features).

These functions work in the same way as the ggplot2 graph functions, but with the following key differences:

- Data must be an `sf` object
- Data must be of `POINT`/`MULTIPOINT`, `LINESTRING`/`MULTILINESTRING`, or `POLYGON`/`MULTIPOLYGON` geometry type
- Data must have a coordinate reference system (CRS) defined
- No `x_var` and `y_var` variables are required
- Borders can added to maps by providing an `sf` object to the `borders` argument.

    example_sf_point
    #> Simple feature collection with 112 features and 3 fields
    #> Geometry type: POINT
    #> Dimension:     XY
    #> Bounding box:  xmin: 1175354 ymin: 4853914 xmax: 2025939 ymax: 6096100
    #> CRS:           EPSG:2193
    #> First 10 features:
    #>      site_id median trend_category                geometry
    #> 1  ARC-00001 0.0140      Improving POINT (1735609 5916179)
    #> 2  ARC-00008 0.0610      Improving POINT (1753479 5976281)
    #> 3  ARC-00013 0.1310      Improving POINT (1742066 5915382)
    #> 4  ARC-00014 0.9900      Improving POINT (1764285 5907017)
    #> 5  ARC-00015 1.0300      Improving POINT (1767401 5907336)
    #> 6  ARC-00016 0.2980      Improving POINT (1768314 5908177)
    #> 7  ARC-00017 0.3550      Improving POINT (1751305 5933319)
    #> 8  ARC-00018 0.7350  Indeterminate POINT (1769952 5912814)
    #> 9  ARC-00019 0.5000      Improving POINT (1769452 5910614)
    #> 10 ARC-00026 0.1295      Improving POINT (1748608 5953465)

    ggplot_sf(example_sf_point,
              size_point = 0.25)

    nz
    #> Simple feature collection with 7 features and 1 field
    #> Geometry type: MULTIPOLYGON
    #> Dimension:     XY
    #> Bounding box:  xmin: 166.4262 ymin: -47.28988 xmax: 178.5505 ymax: -34.39357
    #> CRS:           EPSG:4326
    #>                                       name                       geometry
    #> 1            South Island or Te Waipounamu MULTIPOLYGON (((166.5461 -4...
    #> 2            North Island or Te Ika-a-Maui MULTIPOLYGON (((173.014 -34...
    #> 3                   Stewart Island/Rakiura MULTIPOLYGON (((167.8694 -4...
    #> 4      Great Barrier Island (Aotea Island) MULTIPOLYGON (((175.3966 -3...
    #> 5                        Resolution Island MULTIPOLYGON (((166.6788 -4...
    #> 6 Rangitoto ke te tonga (D'Urville Island) MULTIPOLYGON (((173.9532 -4...
    #> 7                         Secretary Island MULTIPOLYGON (((166.9634 -4...

    ggplot_sf(example_sf_point,
              borders = nz,
              size_point = 0.25)

    example_sf_polygon
    #> Simple feature collection with 963 features and 2 fields
    #> Geometry type: MULTIPOLYGON
    #> Dimension:     XY
    #> Bounding box:  xmin: 1090000 ymin: 4748153 xmax: 2089541 ymax: 6194182
    #> CRS:           EPSG:2193
    #> First 10 features:
    #>    grid_id density                       geometry
    #> 1       12   0.000 MULTIPOLYGON (((1199950 481...
    #> 2       14   0.000 MULTIPOLYGON (((1249363 482...
    #> 3       28 110.454 MULTIPOLYGON (((1259922 485...
    #> 4       88  58.405 MULTIPOLYGON (((1219940 492...
    #> 5       89  62.744 MULTIPOLYGON (((1239931 492...
    #> 6       90  89.362 MULTIPOLYGON (((1259922 492...
    #> 7       91   6.112 MULTIPOLYGON (((1279913 492...
    #> 8      135   0.000 MULTIPOLYGON (((1149972 497...
    #> 9      151   0.000 MULTIPOLYGON (((1139977 499...
    #> 10     167   0.000 MULTIPOLYGON (((1149972 501...

    ggplot_sf_col(example_sf_polygon,
                  col_var = density,
                  borders = nz)

    ggplot_sf_facet(example_sf_point,
                    facet_var = trend_category,
                    borders = nz,
                    size_point = 0.5)

    ggplot_sf_col_facet(example_sf_point,
                        col_var = trend_category,
                        facet_var = trend_category,
                        borders = nz,
                        size_point = 0.5,
                        pal = c("#4575B4", "#D3D3D3", "#D73027"),
                        title = "Site trends, 1990\u201317")

#### ggplot supported variable classes

variable types supported by the different groups of functions are outlined below.

A stat of `identity` refers to the value being plotted as it is. A stat of `boxplot` refers to boxplot statistics being calculated from the data, and these plotted.

    tibble::tribble(
      ~group, ~x_var, ~y_var, ~col_var, ~facet_var, ~stat,
      "vbar", "numeric, date or categorical", "numeric", "categorical or numeric", "categorical", "identity",
      "hbar", "numeric", "categorical", "categorical or numeric", "categorical", "identity",
      "line", "numeric or date", "numeric", "categorical or numeric", "categorical", "identity",
      "point", "numeric", "numeric", "categorical or numeric", "categorical", "identity",
      "boxplot", "Categorical", "numeric", "categorical", "categorical", "boxplot or identity",
      "sf", NA, NA, "categorical or numeric", "categorical", "identity",
      ) %>%
      DT::datatable()

### ggplotly interactive html graphs and maps

All ggplot objects can be converted into interactive html objects using ggplotly. Simply wrap the plot object in `plotly::ggplotly` as follows:

    plot <- ggplot_point(iris, Sepal.Width, Sepal.Length)

    plotly::ggplotly(plot)

For further information on how to use `ggplotly` with `simplevis`, see the ggplotly article

### `sf` leaflet html interactive maps

`simplevis` also provides wrapper functions for `sf` leaflet html interactive maps.

These differ from `ggplotly` interactive plots in that they provide basemaps and zoom functionality. However, they do not support facetting.

A `leaflet_sf` and `leaflet_sf_col` function are provided.

They work in essentially the same way as the ggplot2 non-facetted `sf` functions. Arguments have been aligned with simplevis ggplot wrapping functions (e.g. size_point = radius, line_size = weight, alpha = fillOpacity).

    leaflet_sf_col(example_sf_point,
                   col_var = trend_category,
                   basemap = "light",
                   pal = c("#0D94A3", "#C4C4C7", "#AE4E51"),
                   title = "Monitored trends, 2008\u201317")

For further information on how to create leaflet html maps, see the leaflet article

### Adding layers

Because both of the ggplot and leaflet wrapper functions produce ggplot and leaflet objects, you can add layers in the same way that you would normally to these objects. Be careful to use `+` to add layers to ggplot objects and `%>%` to add to leaflet objects. Data is inherited from the simplevis, but aesthetics are not.

    ggplot_point(iris, Sepal.Width, Sepal.Length) +
      ggplot2::geom_smooth(ggplot2::aes(Sepal.Width, Sepal.Length), col = viridis::viridis(4)[2])

### Colour

To change the colours, add a `pal` argument with a vector of hex strings.

    ggplot_point(iris, Sepal.Width, Sepal.Length, pal = "#e7298a")

    ggplot_point_col(iris, Sepal.Width, Sepal.Length, Species,
                     pal = c("#1B9E77", "#D95F02", "#7570B3"))

Colouring works slightly differently in simplevis to ggplot2. For further information, see the colour article.

### Working with scales

Working with scales can be one of the most challenging aspects of creating a nice visualisation. ’simplevis` uses the power of consistent prefixes and the Rstudio auto-complete to make this easier for users.

For further information, see the scales article.

### Shiny apps for mobile devices

`simplevis` provides simple methods for supporting visualisation on apps for mobile device users.

For further information, see the shiny article.