--- /dev/null
+# Load libraries
+library(sf)
+library(ggplot2)
+library(lubridate)
+library(dplyr)
+library(countrycode)
+
+perf <- read.csv("./performances.csv")
+world_sf <- st_read("../natural-earth/ne_10m_admin_0_countries_lakes.shp", quiet = TRUE)
+world_sf <- st_make_valid(world_sf)
+
+
+genre_colors <- c(
+ performance = "darkmagenta",
+ solo = "blue",
+ chamber = "green",
+ ensemble = "red",
+ electroacoustic = "yellow",
+ open = "white"
+)
+perf$color <- genre_colors[as.character(perf$genre)]
+
+perf$year <- year(mdy(perf$date))
+max_year <- max(perf$year, na.rm = TRUE)
+perf$alpha <- (perf$year - min(perf$year, na.rm = TRUE)) /
+ (max_year - min(perf$year, na.rm = TRUE))
+perf$alpha <- pmax(0.2, perf$alpha)
+
+
+names(world_sf)[names(world_sf) == "ADMIN"] <- "region"
+
+world_sf$subcontinent <- NA_character_
+
+world_sf$subcontinent[world_sf$region %in% c(
+ "Canada", "United States of America", "Mexico", "Guatemala", "Belize", "El Salvador",
+ "Honduras", "Nicaragua", "Costa Rica", "Panama", "Bermuda", "Saint Pierre and Miquelon"
+)] <- "North America"
+
+world_sf$subcontinent[world_sf$region %in% c(
+ "Argentina", "Bolivia", "Brazil", "Chile", "Colombia", "Ecuador", "Guyana",
+ "Paraguay", "Peru", "Suriname", "Uruguay", "Venezuela", "Falkland Islands"
+)] <- "South America"
+
+world_sf$subcontinent[world_sf$region %in% c(
+ "France", "Germany", "Italy", "United Kingdom", "Spain", "Netherlands", "Switzerland",
+ "Austria", "Belgium", "Portugal", "Sweden", "Norway", "Denmark", "Finland", "Ireland",
+ "Poland", "Czechia", "Slovakia", "Hungary", "Greece", "Romania", "Bulgaria", "Ukraine",
+ "Russia", "Serbia", "Croatia", "Slovenia", "Lithuania", "Latvia", "Estonia", "Belarus",
+ "Luxembourg", "Iceland", "Malta", "Bosnia and Herzegovina", "North Macedonia", "Kosovo",
+ "Albania", "Monaco", "Liechtenstein", "Vatican", "San Marino", "Andorra", "Moldova"
+)] <- "Europe"
+
+world_sf$subcontinent[world_sf$region %in% c(
+ "Morocco", "Algeria", "Tunisia", "Libya", "Egypt", "Sudan", "South Sudan", "Ethiopia",
+ "Somalia", "Kenya", "Uganda", "Rwanda", "Burundi", "Tanzania", "Angola", "Zambia",
+ "Zimbabwe", "Namibia", "Botswana", "Mozambique", "Madagascar", "South Africa",
+ "Lesotho", "Eswatini", "Nigeria", "Ghana", "Côte d'Ivoire", "Senegal", "Mali", "Niger",
+ "Chad", "Cameroon", "Central African Republic", "Republic of Congo", "Democratic Republic of the Congo",
+ "Gabon", "Sierra Leone", "Liberia", "Benin", "Togo", "Guinea", "Burkina Faso", "Eritrea",
+ "Mauritania", "Gambia", "Djibouti", "Guinea-Bissau", "Equatorial Guinea", "Comoros",
+ "Seychelles", "Cape Verde", "Sao Tome and Principe"
+)] <- "Africa"
+
+world_sf$subcontinent[world_sf$region %in% c(
+ "China", "India", "Japan", "South Korea", "North Korea", "Thailand", "Vietnam",
+ "Philippines", "Malaysia", "Singapore", "Indonesia", "Myanmar", "Pakistan",
+ "Bangladesh", "Nepal", "Sri Lanka", "Bhutan", "Afghanistan", "Kazakhstan", "Uzbekistan",
+ "Turkmenistan", "Kyrgyzstan", "Tajikistan", "Iran", "Iraq", "Israel", "Jordan",
+ "Lebanon", "Syria", "Saudi Arabia", "United Arab Emirates", "Qatar", "Bahrain",
+ "Kuwait", "Oman", "Yemen", "Georgia", "Armenia", "Azerbaijan", "Mongolia", "Russia"
+)] <- "Asia"
+
+continent_lonlat_bounds <- list(
+ "North America" = list(lon = c(-170, -50), lat = c(7, 85)),
+ "South America" = list(lon = c(-90, -30), lat = c(-60, 15)),
+ "Europe" = list(lon = c(-30, 50), lat = c(35, 72)),
+ "Africa" = list(lon = c(-25, 55), lat = c(-40, 40)),
+ "Asia" = list(lon = c(30, 180), lat = c(5, 80))
+)
+
+perf$subcontinent <- "Other"
+for (cont in names(continent_lonlat_bounds)) {
+ bounds <- continent_lonlat_bounds[[cont]]
+ in_region <- with(perf,
+ lon >= bounds$lon[1] & lon <= bounds$lon[2] &
+ lat >= bounds$lat[1] & lat <= bounds$lat[2])
+ perf$subcontinent[in_region] <- cont
+}
+
+generate_map <- function(map_sf, perf_data, filename,
+ use_projection = TRUE,
+ crs_proj = "EPSG:3395",
+ auto_crop = FALSE) {
+
+ perf_sf <- st_as_sf(perf_data, coords = c("lon", "lat"), crs = 4326, remove = FALSE)
+
+ map_sf <- st_make_valid(map_sf)
+ map_sf <- st_wrap_dateline(map_sf, options = c("WRAPDATELINE=YES", "DATELINEOFFSET=180"))
+
+ if (use_projection) {
+ map_sf <- st_transform(map_sf, crs_proj)
+ perf_sf <- st_transform(perf_sf, crs_proj)
+ }
+
+ if (auto_crop && nrow(perf_sf) > 0) {
+ bbox <- st_bbox(perf_sf)
+ pad <- 1000000
+ bbox[c("xmin", "ymin")] <- bbox[c("xmin", "ymin")] - pad
+ bbox[c("xmax", "ymax")] <- bbox[c("xmax", "ymax")] + pad
+ bbox_sf <- st_as_sfc(bbox)
+ map_sf <- st_crop(map_sf, bbox_sf)
+ perf_sf <- st_crop(perf_sf, bbox_sf)
+ }
+
+ p <- ggplot() +
+ geom_sf(data = map_sf, fill = "black", color = "lightgrey", linewidth = 0.2) +
+ geom_sf(data = perf_sf,
+ aes(color = color, alpha = alpha),
+ shape = 16, size = 1, show.legend = FALSE) +
+ scale_color_identity() +
+ scale_alpha(range = c(0.4, 1)) +
+ theme_void() +
+ theme(panel.background = element_rect(fill = "black", color = NA))
+
+ ggsave(filename = filename,
+ plot = p,
+ width = 8, height = 6, dpi = 400,
+ bg = "black")
+}
+
+generate_map(world_sf, perf, "performance_map_world.png", use_projection = TRUE, crs_proj = "ESRI:54012")
+
+for (cont in unique(world_sf$subcontinent[!is.na(world_sf$subcontinent)])) {
+ map_data <- world_sf[world_sf$subcontinent == cont, ]
+ perf_data <- perf[perf$subcontinent == cont, ]
+ if (nrow(perf_data) > 0) {
+ filename <- paste0("performance_map_", gsub(" ", "_", tolower(cont)), ".png")
+ generate_map(map_data, perf_data, filename, auto_crop = TRUE)
+ }
+}
--- /dev/null
+"date","title","genre","performers","location",lat,lon
+"04/06/2025","Apples & Pairs","solo","Victoria Zhao, Leena Hocutt Duarte","NY, Rochester: Howard Hanson Hall",43.1574640341625,-77.60088239894866
+"03/20/2025","Quads I","chamber","Matchstick Percussion","PA, State College: Recital Hall",40.79939620178565,-77.86717565061629
+"03/04/2025","Net Clarity (Draft)","solo","Amber Lucas, Bethany Brinson","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"02/16/2025","Quads I","chamber","Matchstick Percussion","Washington DC: Atlas Performing Arts Center",38.89997257172797,-76.98746814512847
+"01/13/2025","Quads I","chamber","Matchstick Percussion","Washington DC: Rhizome",38.974150771712246,-77.01562898745422
+"11/17/2024","CO","solo","Katherine Weintraub, Eunmi Ko","OH, Cincinnati: Cohen Family Studio Theatre",39.13086334130582,-84.51779359093011
+"10/05/2024","Quads I","chamber","Matchstick Percussion","Washington DC: Kennedy Center Millennium Stage",38.89588992237243,-77.05551104142666
+"10/04/2024","Improvisation","performance","Tucker Johnson, Floris Van Der Veken (TAPH DUO)","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"10/04/2024","Quartets","electroacoustic","high-order ambisonic playback","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"10/04/2024","Choruses","electroacoustic","Floris Van der Veken","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"09/26/2024","Choruses","electroacoustic","Floris Van der Veken","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"06/01/2024","Quads I","chamber","Matchstick Percussion","PA, Centre Hall: Rhoneymeade Fest",40.809007404011965,-77.72146219109342
+"03/30/2024","Net Clarity","solo","Amber Lucas, Ryena Lee","MI, East Lansing: Cook Recital Hall",42.73224328371995,-84.48438919896427
+"10/16/2023","Circumnutation","solo","Ko Muramatsu, Even Cao, Luke Poeppel","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"06/14/2023","CO","solo","Katherine Weintraub, Eunmi Ko","FL, Saint Petersburg: The Palladium",27.777898661056444,-82.63675721660971
+"03/26/2023","Improvisation","performance","Tucker Johnson, Floris Van Der Veken (TAPH DUO)","NY, Rochester: Kilbourn Hall",43.15770379753868,-77.60130055847137
+"03/24/2023","Settle the Score","electroacoustic","Katie Eaton, Nathan McKinstry, Austin White, Artur Korotin","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"03/03/2023","...for me, the cowbell...","solo","John McGovern","MD, University Park: Gildenhorn Recital Hall",38.99071700319249,-76.95060174697639
+"02/01/2023","Circumnutation","solo","Ko Muramatsu","NY, Rochester: Kilbourn Hall",43.15770379753868,-77.60130055847137
+"11/17/2022","Circumnutation","solo","Zihan Wu","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"11/14/2022","I AM COVERED IN STARCH","electroacoustic","stereo playback","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"10/10/2022","Ossia Fluxus Improvisation","performance","Tucker Johnson, Zoe Markle, Floris Van Der Veken","NY, Rochester: ESM Ray Wright Room",43.15751653080568,-77.60098261375632
+"09/28/2022","Improvisation","performance","Tucker Johnson, Floris Van Der Veken (TAPH DUO)","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"09/19/2022","Circumnutation","solo","Xingyi Chen","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"04/07/2022","Settle the Score","electroacoustic","Katie Eaton, Nathan McKinstry, Logan Barrett, Artur Korotin","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"02/12/2022","Injunctions of Bruckner","electroacoustic","John McGovern","PA, State College: Recital Hall",40.79939620178565,-77.86717565061629
+"02/02/2022","Settle The Score","electroacoustic","quadrophonic playback","NY, Rochester: Kilbourn Hall",43.15770379753868,-77.60130055847137
+"11/10/2021","Commonplace Common Tones","ensemble","Eastman Graduate Composers' Sinfonietta, Nicholas Sharma","NY, Rochester: Kilbourn Hall",43.15770379753868,-77.60130055847137
+"07/04/2021","Enter Ghost","chamber","Loadbang","MA, Boston: Longy School of Music",42.37863142588215,-71.12354617754511
+"05/04/2021","Injunctions of Bruckner","electroacoustic","John McGovern","MD, University Park: Gildenhorn Recital Hall",38.99071700319249,-76.95060174697639
+"04/25/2021","Falling Paths, Coloring Grounds","electroacoustic","Hudson Webber","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"04/24/2021","The Ecstasy of Communication","electroacoustic","John McGovern","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"04/24/2021","A Presence Within Reassembly","electroacoustic","quadrophonic playback","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"04/24/2021","Wears and Tears","electroacoustic","Amber Lucas","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"04/24/2021","Falling Paths, Coloring Grounds","electroacoustic","Hudson Webber","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"04/24/2021","Injunctions of Bruckner","electroacoustic","John McGovern","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"04/16/2021","Wears and Tears","electroacoustic","Amber Lucas","PA, State College: Esber Recital Hall",40.79939620178565,-77.86717565061629
+"04/09/2021","A Presence Within Reassembly","electroacoustic","stereo playback","NY, Rochester: Hatch Recital Hall",43.158346126572596,-77.60053200265061
+"03/30/2021","Wears and Tears","electroacoustic","Amber Lucas","PA, State College: Online Event",40.79939620178565,-77.86717565061629
+"11/20/2020","The Ecstasy of Communication","electroacoustic","John McGovern","MD, University Park: Gildenhorn Recital Hall",38.99071700319249,-76.95060174697639
+"10/23/2020","A Presence Within Reassembly","electroacoustic","quadrophonic playback","PA, State College: Water Tower Plaza",40.800613247794644,-77.86739713021983
+"07/05/2020","All of My Life's Work Until This Point","solo","Eduard Teregulov","FL, Dade City: Online Event",28.364606390549227,-82.18438421659572
+"12/02/2019","---------","electroacoustic","stereo playback","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/22/2019","Or Maybe While Crossing","chamber","Corvus Ensemble","NY, NYC: Federal Hall Memorial",40.70739927139852,-74.01028390458946
+"11/07/2019","WE CANNOT POST IN SUMMER","ensemble","USF Student Sinfonietta","FL, Tampa: Contemporary Art Museum at USF",28.06356828850554,-82.41556563965035
+"10/12/2019","CO","solo","Doug O'Connor, Eunmi Ko","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"10/09/2019","Mobility, on beauty","performance","collaborative installation","FL, Tampa: USF Theatre 2",28.063615625492695,-82.41496482478618
+"10/17/2019","I AM COVERED IN STARCH","electroacoustic","stereo playback","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"08/10/2019","References to the Antichrist in eccleciastical writings","solo","Bennet Astrove","FL, Dade City: Heritage and Cultural Museum",28.364606390549227,-82.18438421659572
+"07/12/2019","WRITE/TAKE","solo","Dieter Hennings, John Rivera Pico","Italy, Cesena: Conservatorio Bruno Maderna",44.13613332082202,12.249839305325395
+"05/31/2019","CO","solo","Changhoon Lee, Jien Shin","South Korea, Jeonju: Sori Arts Center",35.85606789442302,127.13828461244562
+"05/11/2019","JetFuel","ensemble","Tampa Metropolitan Youth Orchestra, William Weidrich","FL, Tampa: Concert Hall at USF",28.065035726363902,-82.41816201792611
+"04/22/2019","All of My Life's Work Until This Point","solo","Sydney Andersen","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"02/22/2019","A Different City*The Cold Part","performance","RAMP GROUP","FL, Tampa: Contemporary Art Museum at USF",28.06356828850554,-82.41556563965035
+"02/08/2019","Four Weeks Now","chamber","Luz Vasquez, KaleyAnna Raabe, Daphne Waggener, Sydney Andersen","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/26/2018","The Identity of Policing","electroacoustic","stereo playback","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/17/2018","Space Flight Participant","solo","Keon Sahbkar","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/17/2018","Would Also Feel the Need to Enjoy","solo","Sohyun Lim","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/17/2018","This First Semester is Dedicated","solo","Brianna Mikesel, Tucker Johnson","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/17/2018","There’s almost never a point in time when there’s no one walking in the hallways","electroacoustic","stereo playback","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/17/2018","References to the Antichrist in eccleciastical writings","solo","Bennet Astrove","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"11/17/2018","Time in North Dakota","solo","Daphne Waggnener","FL, Saint Petersburg: Studio 620",27.7700897746876,-82.64216604544569
+"11/16/2018","Space Flight Participant","solo","Keon Sahbkar","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"09/29/2018","Time in North Dakota","solo","Daphne Waggnener","FL, Saint Petersburg: Studio 620",27.7700897746876,-82.64216604544569
+"09/27/2018","Time in North Dakota","solo","Daphne Waggnener","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"09/27/2018","References to the Antichrist in eccleciastical writings","solo","Bennet Astrove","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"09/02/2018","There’s almost never a point in time when there’s no one walking in the hallways","electroacoustic",stereo playback,"FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"08/12/2018","...for the discernment of vocations with...","chamber","Shawn Mativetsky, New Jersey Percussion Ensemble","NJ, Wayne: William Patterson University",40.9475183210728,-74.19660784135644
+"04/16/2018","Numlock","chamber","Kevin Baylen, Vagelis Petropolous, Han Hitchen, Brendon Sill, Alexandro Russo","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"04/13/2018","Numlock","chamber","Kevin Baylen, Vagelis Petropolous, Han Hitchen, Brendon Sill, Alexandro Russo","FL, Tampa: USF Instrumental Rehearsal Hall",28.064543364944004,-82.41795818714309
+"03/05/2018","Grater Brute","solo","Kevin Baylen, Lionel Martinez","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"03/02/2018","Transportation in Metropolitan Detroit","solo","Logan Barrett","FL, Tampa: USF Choral Rehearsal Hall",28.064543364944004,-82.41795818714309
+"03/02/2018","Grater Brute","solo","Kevin Baylen, Lionel Martinez","FL, Tampa: USF Choral Rehearsal Hall",28.064543364944004,-82.41795818714309
+"11/17/2017","r9-13\I TERDI...","solo","Kaycie Howell","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"10/20/2017","Transportation in Metropolitan Detroit","solo","Logan Barrett","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"07/08/2017","In the Shape of the sky","chamber","Kinhaven Student Ensemble","VT, Weston: Kinhaven School of Music",43.31373476709863,-72.7936920602979
+"05/08/2017","Walkin' With Billy","chamber","PCCA Student Ensemble","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"05/08/2017","Designations","solo","Kendric McCallister","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"12/07/2016","Walkin' With Billy","chamber","PCCA Student Ensemble","FL, Tampa: Barness Recital Hall",28.064543364944004,-82.41795818714309
+"07/29/2016","Morning Chase","ensemble","Kinhaven Student Ensemble","VT, Weston: Kinhaven School of Music",43.31373476709863,-72.79369206029793
+"07/29/2016","Letters Unwritten","chamber","Kinhaven Student Ensemble","VT, Weston: Kinhaven School of Music",43.31373476709863,-72.79369206029793
+"05/24/2016","Ephemeral Sketches","solo","Britney Waggot, Miranda Godfrey","FL, Saint Petersburg: PCCA",27.843811802722946,-82.70129640199329
+"05/24/2016","Letters Unwritten","chamber","PCCA Student Ensemble","FL, Saint Petersburg: PCCA",27.843811802722946,-82.70129640199329