Skip to content

Geo-99/bubblegam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bubblegamlogo

Welcome to bubblegam! An R package to efficiently merge (geo)dataframes, identify, and move "spatial outliers" in geodata, create geographic plots, bubbleplots, and the animation between these plots.  

Authors: Georg Starz (Code) & Anna Bischof (Code, Package Idea)

Contact: georg.starz@stud-mail.uni-wuerzburg.de & anna.bischof@stud-mail.uni-wuerzburg.de

 

Plot & animation examples

animation_green_delayedData source: Destatis

 

animation_footprint_delayedData source: EDGAR

 

animation_usa_outline_delayedData source: STATSAMERICA

 

Installation

The package was developed with R version 4.3.1 on Windows. Mac & Linux haven't been tested so far. To install and load bubblegam, enter these commands in your R console:  

library(devtools)
install_github("Geo-99/bubblegam")
library(bubblegam)

When testing the package we encountered some yet to be solved issues with two package dependencies. Therefore, for now, we recommend manually loading library(animation) & library(sf).

 

Example workflow to demonstrate the different functions

Here, we want to create this animation (based on a geopackage of the federal states of Spain and data on the GDP):

 

animation_red_edge_delayed

 

For a detailed description of all functions and their parameters, refer to the documentation, e.g. ?find_sim_change.

 

The source data is supplied with the installation of the package.spain_gdp is a data.frame and spain_gpkg is a sf data.frame. We use the find_sim_change function to synchronize the names of the Spanish federal states for the subsequent merge function. There are three features, which are spelled slightly differently in the two datasets:  

gdp_cleaned <- find_sim_change(df_main = spain_gpkg, df_main_col = "Texto",
                                df_change = spain_gdp, df_change_col = "CCAA")

Then, we merge both dataframes with merge_gd_df:  

spain_merged <- merge_gd_df(gdf_left = spain_gpkg, id_left = "Texto",
                            df_right = gdp_cleaned, id_right = "CCAA")

 

Optional: "Spatial outliers" in the geodata (in this case the Canary Islands) can complicate the map display. To automatically identify and then delete/define these outliers use outlier_identify and answer the prompts in the console (warnings may be displayed, which can be ignored):  

spain_merged_outliers <- outlier_identify(geodata = spain_merged, id_col = "Texto")

If the Canary Islands were defined as an outlier, their multipolygon can be "moved closer" towards mainland Spain using outlier_moving:  

spain_merged_moved <- outlier_moving(geodata = spain_merged_outliers)

Step2

 

Use create_bubbles to create the bubble geodata:  

spain_bubbles <- create_bubbles(merged_gdf = spain_merged_moved, col_name = "PIB_anual_EURO")

We define the plot limit coordinates by referring to both geodataframes (map & bubbles) using define_limits. Note: This is done to ensure a consistent plot extent within the animation:

spain_limits_combined <- define_limits(data_start = spain_merged_moved, data_end = spain_bubbles)

Next, we can create our start and bubble plot with plot_cont (you can then save the plots using ggsave()):  

spain_plot <-  plot_cont(gdf = spain_merged_moved, column = "PIB_Per_Capita_EURO",     
                          plot_limits = spain_limits_combined,
                          fill_colorscale = c("lightyellow", "#f1434a","darkred"),
                          legend_limits = c(20000,40000),
                          edge_color = "#323232", edge_width = 0.1,
                          legend_text = 14,
                          title = "GDP per Capita in Spain 2022 [€]",
                          title_size = 24)
spain_plot

bubbles_plot <- plot_cont(gdf = spain_bubbles, column = "PIB_Per_Capita_EURO",     
                          plot_limits = spain_limits_combined,
                          fill_colorscale = c("lightyellow", "#f1434a","darkred"),
                          legend_limits = c(20000,40000),
                          edge_color = "#323232", edge_width = 0.1,
                          legend_text = 14,
                          title = "GDP per Capita in Spain 2022 [€]\n→ Bubble Size: Total GDP per state",
                          title_size = 24)
bubbles_plot

 

Now, to start the creation of the animation, we first need to calculate the transition steps between spain_gdp_moved and spain_bubbles by using create_transition (warnings may be displayed, which can be ignored):

spain_transition <- create_transition(gdf = spain_merged_moved, bubble_gdf = spain_bubbles, 
                                      color_col = "PIB_Per_Capita_EURO", bubble_col = "PIB_anual_EURO")

anim_cont_raw is used to create the raw animation (slow sequence of all frames) and save it. Note: all parameters from plot_limits onwards are based on plot_cont:

anim_cont_raw(transition_df = spain_transition, path_file_name = "path/to/anim_raw.gif",
              anim_width = 1900, anim_height = 2000, anim_res = 400,
              plot_limits = spain_limits_combined,
              fill_colorscale = c("lightyellow", "#f1434a","darkred"),
              legend_limits = c(20000,40000),
              edge_color = "#323232", 
              legend_text = 10,
              title = "GDP per Capita in Spain 2022 [€]\n→ Bubble Size: Total GDP per state",
              title_face = "bold", title_size = 15)

To define the frames per second of the animation and add a delay at the start and end plot use anim_finalize:

anim_finalize(anim_raw = "path/to/anim_raw.gif", anim_path_file = "path/to/anim_final.gif",
              fps_anim = 10, delay_anim = TRUE, delay_frames = 60)

 

Creating the animation can be quite time-intensive depending on the input data. As an alternative, you can use the following code to create a higher-resolution animation (execute as a whole). However, in our experience, this takes even longer:

library(magick)

img <- image_graph()
datalist <- split(spain_transition, spain_transition$.frame)
sf_datalist <- lapply(datalist, function(datalist) st_as_sf(datalist))
out <- lapply(sf_datalist, plot_cont,
              column = "v_plot1", plot_limits = spain_limits_combined,
              fill_colorscale = c("lightyellow", "#f1434a","darkred"),
              legend_limits = c(20000,40000),
              edge_color = "#323232", edge_width = 0.2,
              legend_text = 14,
              title = "GDP per Capita in Spain 2022 [€]\n→ Bubble Size: Total GDP per state",
              title_face = "bold", title_size = 24)
out
dev.off()

animation <- image_animate(img, fps = 10)
animation_delayed <- animation[c(rep(1, each = 60), 2:(length(datalist)-1), rep(length(datalist), each = 60))]

image_write(animation, "path/to/anim_fps.gif")
image_write(animation_delayed, "path/to/anim_fps_delayed.gif")

 

Further notes

  • We are happy if you find our bubblegam package useful! When using it, please link our repo (e.g., like so: bubblegam R package, https://github.com/Geo-99/bubblegam)
  • Feel free to send us plots and animations that you have created with bubblegam :)
  • We are sure there are many possible code improvements. We're looking forward to any suggestions you might have!
  • 4 bubblegam functions weren't shown in the Spain GDP example:
    • merge_df_df enables inner merge of dataframes similar to merge_gd_df
    • outlier_restructure reincludes moved outlier subfeatures
    • plot_discr: same as plot_cont but for discrete data
    • anim_discr_raw: same as anim_cont_raw but for discrete data

 

Current Developments

We are currently working on extending the functionality of bubblegam. Below you can find a list on what we are working on.

  • Function to create an animation between different plots or images. The aim is to facilitate the morph transition between the plots. function_anim_transp_small

 

  • Option to create a cartogram animation. anim_raw_largestpartFALSE_FINAL2

 

  • Option to create a time series animation based on multiple bubble plots over time. africa_1980_2021_3_FINAL gif

 

Common problems

  • If your geodata uses a geographic and not a projected CRS, the bubbles can turn into ellipses in the plots/animations. Therefore, we recommend reprojecting it beforehand using st_transform().animation
  • To be continued ...

 

Acknowledgements

This package is inspired by and partly based on zumbov2's Switzerland version of Karim Douïeb's famous vizualization Land Doesn't Vote... People Do.

We want to thank Dr. Martin Wegmann and the Earth Observation Research Cluster's DevLab for the support and feedback during the development of the package.

This is a submission for the course Introduction to Programming and Statistics for Remote Sensing and GIS as part of the M.Sc. EAGLE program at the University of Würzburg.

 

Appendix

switz_plot

 

switz_bubbles_plot

 

animation_cantons

 

animation_cantons_smaller_outline

 

animation_NEW_delayed

 

Spain_red_bubbles_borders

 

plot_UNFCC

About

Merge (geo)dataframes, identify, and move "spatial outliers" in geodata, create geographic plots, bubbleplots, and the animation between these plots.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages