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:
The package also supports making mobile-friendly visualisation for mobile devices.
simplevis provides the following families of ggplot2 visualisation:
Graph:
ggplot_hbar)ggplot_vbar)ggplot_line)ggplot_point)ggplot_boxplot)Map:
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:
datax_var (not required for sf)y_var (not required for sf)If you are using a _col or _col_facet function:
col_varIf you are using a _facet or _col_facet function:
facet_varIt is always recommended to add a title, x_title and y_title too.
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)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)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)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 mapssimplevis 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:
sf objectPOINT/MULTIPOINT, LINESTRING/MULTILINESTRING, or POLYGON/MULTIPOLYGON geometry typex_var and y_var variables are requiredsf 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_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")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()All ggplot objects can be converted into interactive html objects using ggplotly. Simply wrap the plot object in plotly::ggplotly as follows:
For further information on how to use ggplotly with simplevis, see the ggplotly article
sf leaflet html interactive mapssimplevis 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
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])To change the colours, add a pal argument with a vector of hex strings.
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 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.
simplevis provides simple methods for supporting visualisation on apps for mobile device users.
For further information, see the shiny article.