Analysis of Urban Tree Cover: City of Buffalo 2024

Ecological Benefits Analysis

Author

Jack Mernitz

Published

December 3, 2024

Introduction

Trees are often overlooked as a component of urban spaces. With so much focus on the growth of infrastructure, living space, and work spaces, green places are left little room to grow. Tree leaf area coverage, while possibly annoying for lawn owners in the fall, is directly related to shade capacity and other environmental benefits of trees. Permeable surfaces where trees grow also reduce runoff, trees cool the surrounding air in sufficient density, and the mental and aesthetic benefits of green spaces in urban areas for residents and tourists are notable. Urban forestry bureaus seek to classify and present some of these benefits to the public.

Quantifying and estimating the possible value of these services in relation to tree occurrence seemed like an interesting topic to delve into. Vacant spots and stumps of former trees cannot provide benefits any longer. While an intensive endeavor to replace fully grown trees, my project seeks to enumerate how useful it could be to increase tree cover. Parsing data to assign relative values for comparable trees will assist in more accurate estimation of services. Individual versus collective benefit will also be questioned, but only after calculation of total possible benefits are complete.

Materials and methods

The Dataset

Publicly available data from the City of Buffalo Department of Public Works: Bureau of Forestry exists as a list of tree inventory within the City proper. This includes multiple categories to represent trees’ ecosystem services. Downloading and processing this data is necessary, as there are 133,229 entries in the dataset. The data is organized into 28 columns, and each row is a tree site. It is a daily updated dataset existing since 2018.

Install and Load Packages

Code
install.packages("mapview")
install.packages("webshot")
install.packages("hrbrthemes")
library(tidyverse)
library(dplyr)
library(ggplot2)
library(hrbrthemes)
library(mapview)
library(webshot)
library(sf)
library(kableExtra)
library(htmlwidgets)
library(widgetframe)
knitr::opts_chunk$set(widgetframe_widgets_dir = 'widgets' ) 
knitr::opts_chunk$set(cache=TRUE)  # cache the results for quick compiling

Downloading the required data

Code
tree_data <- read.csv("https://data.buffalony.gov/api/views/n4ni-uuec/rows.csv?accessType=DOWNLOAD")

A sample of how the dataset is organized.

Code
tree_data %>% 
  slice(1:5) %>% #show only 1:5 rows
  kable(digits=2,align="c")%>% #make table and round to two digits
  kable_styling(bootstrap_options = 
                  c("striped", "hover", "condensed", "responsive")) 
Editing Botanical.Name Common.Name DBH Total.Yearly.Eco.Benefits.... Stormwater.Benefits.... Stormwater.Gallons.Saved Greenhouse.CO2.Benefits.... CO2.Avoided..in.lbs.. CO2.Sequestered..in.lbs.. Energy.Benefits.... kWh.Saved Therms.Saved Air.Quality.Benefits.... Pollutants.Saved..in.lbs.. Property.Benefits.... Leaf.Surface.Area..in.sq..ft.. Address Street Side Site Council.District Park.Name Latitude Longitude Site.ID Location location
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 250 Minnesota Av Front 1 University 0 42.95 -78.82 73961 (42.9466215137, -78.8202132436) POINT (-78.8202132436 42.9466215137)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 Eggert Rd Side 1 University 0 42.95 -78.80 75828 (42.9480502373, -78.8037997246799) POINT (-78.8037997246799 42.9480502373)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 164 Rounds Av Front 1 University 0 42.95 -78.81 75879 (42.9474045086, -78.8074540366) POINT (-78.8074540366 42.9474045086)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 Rounds Av Front 1 University 0 42.95 -78.81 75922 (42.9473611754, -78.8120223129) POINT (-78.8120223129 42.9473611754)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 559 Potomac Av Front 1 Delaware 0 42.92 -78.88 50106 (42.92413835322631, -78.87850124740001) POINT (-78.87850124740001 42.92413835322631)

Filter out ‘unsuitable vacant’ and ‘0’ sites.

Code
tree_suitable <- tree_data %>%
  filter(tree_data[,2] != "unsuitable vacant")

tree_filtered <- tree_suitable %>%
  filter(tree_suitable[,3] != "0")
print(paste("The length of tree_filtered is ", nrow(tree_data) - nrow(tree_filtered), "rows smaller."))
[1] "The length of tree_filtered is  566 rows smaller."
Code
rm(tree_data)
rm(tree_suitable)

Resulting data split into vacant, stump, and used sites and compared.

Code
stump_data <- tree_filtered %>%
  filter(tree_filtered[,2] == "STUMP")

vacant_data <- tree_filtered %>%
  filter(tree_filtered[,2] == "VACANT")

treeonly_data <- tree_filtered %>%
  filter(!(tree_filtered[,2] %in% c("STUMP", "VACANT")))

stump_data %>%
  head(5) %>%
  kable() %>%
  kable_styling(bootstrap_options = 
                  c("striped", "hover", "condensed", "responsive"))
Editing Botanical.Name Common.Name DBH Total.Yearly.Eco.Benefits.... Stormwater.Benefits.... Stormwater.Gallons.Saved Greenhouse.CO2.Benefits.... CO2.Avoided..in.lbs.. CO2.Sequestered..in.lbs.. Energy.Benefits.... kWh.Saved Therms.Saved Air.Quality.Benefits.... Pollutants.Saved..in.lbs.. Property.Benefits.... Leaf.Surface.Area..in.sq..ft.. Address Street Side Site Council.District Park.Name Latitude Longitude Site.ID Location location
Buffalo STUMP STUMP 10 0 0 0 0 0 0 0 0 0 0 0 0 0 195 Starin Av Front 1 Delaware 0 42.94576 -78.84398 64856 (42.945757008, -78.8439754343) POINT (-78.8439754343 42.945757008)
Buffalo STUMP STUMP 6 0 0 0 0 0 0 0 0 0 0 0 0 0 95 Franklin St Side 1 Fillmore 0 42.88353 -78.87691 125974 (42.88352559989959, -78.87690519735564) POINT (-78.87690519735564 42.88352559989959)
Buffalo STUMP STUMP 2 0 0 0 0 0 0 0 0 0 0 0 0 0 326 Bird Av Front 1 Niagara 0 42.92595 -78.88687 34850 (42.925954502716685, -78.88687446297482) POINT (-78.88687446297482 42.925954502716685)
Olmsted STUMP STUMP 6 0 0 0 0 0 0 0 0 0 0 0 0 0 2182 Delaware Av Median 134 Delaware Delaware 42.93059 -78.86555 96553 (42.9305869665, -78.8655480659) POINT (-78.8655480659 42.9305869665)
Olmsted STUMP STUMP 9 0 0 0 0 0 0 0 0 0 0 0 0 0 225 Abbott Rd In_Lot 1 South Heacock 42.85546 -78.82317 107081 (42.85546040655967, -78.82317379145495) POINT (-78.82317379145495 42.85546040655967)
Code
vacant_data %>%
  head(5) %>%
  kable() %>%
  kable_styling(bootstrap_options = 
                  c("striped", "hover", "condensed", "responsive"))
Editing Botanical.Name Common.Name DBH Total.Yearly.Eco.Benefits.... Stormwater.Benefits.... Stormwater.Gallons.Saved Greenhouse.CO2.Benefits.... CO2.Avoided..in.lbs.. CO2.Sequestered..in.lbs.. Energy.Benefits.... kWh.Saved Therms.Saved Air.Quality.Benefits.... Pollutants.Saved..in.lbs.. Property.Benefits.... Leaf.Surface.Area..in.sq..ft.. Address Street Side Site Council.District Park.Name Latitude Longitude Site.ID Location location
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 250 Minnesota Av Front 1 University 0 42.94662 -78.82021 73961 (42.9466215137, -78.8202132436) POINT (-78.8202132436 42.9466215137)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 Eggert Rd Side 1 University 0 42.94805 -78.80380 75828 (42.9480502373, -78.8037997246799) POINT (-78.8037997246799 42.9480502373)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 164 Rounds Av Front 1 University 0 42.94740 -78.80745 75879 (42.9474045086, -78.8074540366) POINT (-78.8074540366 42.9474045086)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 Rounds Av Front 1 University 0 42.94736 -78.81202 75922 (42.9473611754, -78.8120223129) POINT (-78.8120223129 42.9473611754)
Buffalo VACANT VACANT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 559 Potomac Av Front 1 Delaware 0 42.92414 -78.87850 50106 (42.92413835322631, -78.87850124740001) POINT (-78.87850124740001 42.92413835322631)
Code
treeonly_data %>%
  head(5) %>%
  kable() %>%
  kable_styling(bootstrap_options = 
                  c("striped", "hover", "condensed", "responsive"))
Editing Botanical.Name Common.Name DBH Total.Yearly.Eco.Benefits.... Stormwater.Benefits.... Stormwater.Gallons.Saved Greenhouse.CO2.Benefits.... CO2.Avoided..in.lbs.. CO2.Sequestered..in.lbs.. Energy.Benefits.... kWh.Saved Therms.Saved Air.Quality.Benefits.... Pollutants.Saved..in.lbs.. Property.Benefits.... Leaf.Surface.Area..in.sq..ft.. Address Street Side Site Council.District Park.Name Latitude Longitude Site.ID Location location
Buffalo MALUS SPP CRABAPPLE 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 403 Plymouth Av Front 1 Niagara 0 42.90815 -78.89169 46037 (42.9081507486, -78.891686234) POINT (-78.891686234 42.9081507486)
Olmsted ULMUS SPP ELM, SPECIES 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 126 Chapin Pkwy Median 1 Delaware Chapin Parkway 42.92362 -78.87137 55220 (42.923621397252866, -78.8713734877264) POINT (-78.8713734877264 42.923621397252866)
Buffalo TILIA CORDATA LINDEN, LITTLELEAF 17 119.46 11.58 1447.65 1.16 280.83 159.72 62.69 98.35 34.74 10.47 1.75 33.55 55.77 1550 Kensington Av Front 1 University 0 42.94383 -78.79951 77077 (42.94382567698975, -78.79951059464187) POINT (-78.79951059464187 42.94382567698975)
Buffalo CERCIDIPHYLLUM JAPONICUM KATSURATREE 6 73.02 1.60 199.89 0.03 5.09 3.87 19.47 24.19 11.42 0.39 0.06 51.53 85.64 24 Crescent Av Front 1 Delaware 0 42.92946 -78.85172 63798 (42.92946461230632, -78.85171585637357) POINT (-78.85171585637357 42.92946461230632)
Buffalo ULMUS X ELM, HYBRID 20 214.82 7.74 967.55 0.16 30.76 26.90 95.32 146.18 53.15 2.27 0.32 109.33 181.71 2182 Delaware Av Rear 1 Delaware 0 42.93121 -78.87571 109161 (42.93121326991395, -78.87570957866497) POINT (-78.87570957866497 42.93121326991395)
Code
rm(tree_filtered)

Species count analysis.

Code
treeonly_data %>%
  # Count occurrences of each tree species col3
  count(!!sym(names(treeonly_data)[3])) %>% 
  arrange(n) %>%  # Sort by count
  top_n(15, n) %>%
  mutate(!!names(treeonly_data)[3] := factor(!!sym(names(treeonly_data)[3]), levels = unique(!!sym(names(treeonly_data)[3])))) %>%  # Factor for ordered axis
  ggplot(aes(x = !!sym(names(treeonly_data)[3]), y = n)) +  # Use the count (n) on the y-axis
    geom_segment(aes(x = !!sym(names(treeonly_data)[3]), xend = !!sym(names(treeonly_data)[3]), y = 0, yend = n), color = "gray") +  # Add segments (bars)
    geom_point(size = 3, color = "#654194") +  # Add points (dots)
    coord_flip() +  # Flip coordinates to make the plot horizontal (lolipop graph)
    theme_ipsum() +  # Apply hrbrthemes style
    theme(
      panel.grid.minor.y = element_blank(),
      panel.grid.major.y = element_blank(),
      legend.position = "none"  # Hide the legend
    ) +
    xlab("") 

Code
top_15_counts <- treeonly_data %>%
  count(!!sym(names(treeonly_data)[3])) %>%
  arrange(desc(n)) %>%  # Sort by count in descending order
  slice_max(n, n = 15)  

#sum of 15 greatest
total_count <- sum(top_15_counts$n)

# Add the proportion column
top_15_counts <- top_15_counts %>%
  mutate(proportion = n / total_count)

portion_total <- total_count/70163

Top 15 Species

Code
print(top_15_counts)
                Common.Name    n proportion
1             MAPLE, NORWAY 8837 0.21770300
2        LINDEN, LITTLELEAF 8330 0.20521285
3             MAPLE, SILVER 4266 0.10509460
4                MAPLE, RED 2390 0.05887860
5              MAPLE, HEDGE 2291 0.05643969
6       MAPLE, CRIMSON KING 1795 0.04422054
7         LILAC, IVORY SILK 1703 0.04195408
8               HONEYLOCUST 1539 0.03791387
9    ELM, CHRISTINE BUISMAN 1526 0.03759361
10                CRABAPPLE 1479 0.03643575
11 MAPLE, DEBORAH SCHWEDLER 1409 0.03471127
12         LONDON PLANETREE 1333 0.03283898
13            PEAR, CALLERY 1268 0.03123768
14         OAK, SWAMP WHITE 1221 0.03007982
15          LINDEN, CRIMEAN 1205 0.02968565
Code
print(portion_total)
[1] 0.5785385

From this, we can also see the top 15 species only make up 57.8% of the total tree count.

Assessment of resource values by species.

Code
top_eco <- treeonly_data %>%
  group_by(!!sym(names(treeonly_data)[3])) %>%  # Group by species
  summarise(total = sum(!!sym(names(treeonly_data)[5]), na.rm = TRUE)) %>%  
  arrange(desc(total)) %>%  # Sort by total value in descending order
  slice_max(total, n = 15)  # Keep top 15 categories by total sum

# Bar graph for top totals from column 5
top_eco %>%
  ggplot(aes(x = !!sym(names(top_eco)[1]), y = total, fill = as.factor(!!sym(names(top_eco)[1])))) +  # Use category for x-axis and fill by category
  geom_bar(stat = "identity") +  # Bar graph with stat = "identity" to use the actual totals
  geom_text(aes(label = total), angle = 90, hjust = .4, size = 5) +
  scale_y_continuous(limits = c(0, 1300000)) +
  theme(
    axis.text.x = element_blank(),   # Remove x-axis tick labels
    axis.ticks.x = element_blank()   # Remove x-axis ticks
  ) +
  labs(fill = "Common Name", title = "Ecological Yearly Benefits of Top 15 Species") +
  xlab("Trees") +
  ylab("Benefits in Dollars")

This shows the most ecologically beneficial tree species and their associated value. We’ll also assume people do not want to go to the trouble of removing stumps first, so let’s focus on vacant spots. We know that people will want to pick popular choices, so we’ll use the 15 most popular species to assign trees to vacant sites.

Results

Proportionate species distribution assigned to vacant sites.

Code
# Calculate how many times each species should be assigned to vacant_data
vacant_count <- nrow(vacant_data)  # matches

# Calculate numb of times each species should appear in vacant_data
top_15_counts <- top_15_counts %>%
  mutate(count_vacant = round(proportion * vacant_count))

# Create a vector of species names, repeated according to count_vacant
reassigned_data <- rep(top_15_counts$Common.Name, top_15_counts$count_vacant)

# Randomly shuffle the species names in vacant_reassigned_data
set.seed(426)  # Set the seed to ensure reproducibility
reassigned_data <- sample(reassigned_data)

# Adjust the length of vacant_reassigned_data to match vacant_data
# Ensure it has exactly the same number of observations as vacant_data (60559)
reassigned_data <- sample(reassigned_data, vacant_count, replace = TRUE)

# Replace the "Common.Name" column (column 3) in vacant_data with reassigned species
vacant_data$Common.Name <- reassigned_data

vacant_data %>%
  head(5) %>%
  kable() %>%
  kable_styling(bootstrap_options = 
                  c("striped", "hover", "condensed", "responsive"))
Editing Botanical.Name Common.Name DBH Total.Yearly.Eco.Benefits.... Stormwater.Benefits.... Stormwater.Gallons.Saved Greenhouse.CO2.Benefits.... CO2.Avoided..in.lbs.. CO2.Sequestered..in.lbs.. Energy.Benefits.... kWh.Saved Therms.Saved Air.Quality.Benefits.... Pollutants.Saved..in.lbs.. Property.Benefits.... Leaf.Surface.Area..in.sq..ft.. Address Street Side Site Council.District Park.Name Latitude Longitude Site.ID Location location
Buffalo VACANT MAPLE, SILVER 0 0 0 0 0 0 0 0 0 0 0 0 0 0 250 Minnesota Av Front 1 University 0 42.94662 -78.82021 73961 (42.9466215137, -78.8202132436) POINT (-78.8202132436 42.9466215137)
Buffalo VACANT MAPLE, CRIMSON KING 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 Eggert Rd Side 1 University 0 42.94805 -78.80380 75828 (42.9480502373, -78.8037997246799) POINT (-78.8037997246799 42.9480502373)
Buffalo VACANT OAK, SWAMP WHITE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 164 Rounds Av Front 1 University 0 42.94740 -78.80745 75879 (42.9474045086, -78.8074540366) POINT (-78.8074540366 42.9474045086)
Buffalo VACANT MAPLE, NORWAY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 Rounds Av Front 1 University 0 42.94736 -78.81202 75922 (42.9473611754, -78.8120223129) POINT (-78.8120223129 42.9473611754)
Buffalo VACANT MAPLE, CRIMSON KING 0 0 0 0 0 0 0 0 0 0 0 0 0 0 559 Potomac Av Front 1 Delaware 0 42.92414 -78.87850 50106 (42.92413835322631, -78.87850124740001) POINT (-78.87850124740001 42.92413835322631)

We now have reassigned the 15 most populous trees to the vacant_data dataset.

Take totals data and find eco value per tree.

Code
eco_summary <- treeonly_data %>%
  group_by(!!sym(names(treeonly_data)[3])) %>%  # Group by species (Common.Name)
  summarise(
    total_benefit = sum(!!sym(names(treeonly_data)[5]), na.rm = TRUE),  # Sum of eco benefit
    count = n(),  # Occurrences of each species
    avg_benefit = total_benefit / count  # Calculate the average ecological value
  ) %>%
  arrange(desc(count)) %>%  # Sort by count
  slice_max(count, n = 15)  # Top 15 species based on count
#Display
eco_summary
# A tibble: 15 × 4
   Common.Name              total_benefit count avg_benefit
   <chr>                            <dbl> <int>       <dbl>
 1 MAPLE, NORWAY                 1174347.  8837       133. 
 2 LINDEN, LITTLELEAF             879114.  8330       106. 
 3 MAPLE, SILVER                  808015.  4266       189. 
 4 MAPLE, RED                     235416.  2390        98.5
 5 MAPLE, HEDGE                   221641.  2291        96.7
 6 MAPLE, CRIMSON KING            213066.  1795       119. 
 7 LILAC, IVORY SILK               39388.  1703        23.1
 8 HONEYLOCUST                    206061.  1539       134. 
 9 ELM, CHRISTINE BUISMAN         363742.  1526       238. 
10 CRABAPPLE                       51863.  1479        35.1
11 MAPLE, DEBORAH SCHWEDLER       152217.  1409       108. 
12 LONDON PLANETREE               250481.  1333       188. 
13 PEAR, CALLERY                  212454.  1268       168. 
14 OAK, SWAMP WHITE                89763.  1221        73.5
15 LINDEN, CRIMEAN                189780.  1205       157. 

##Project environmental benefits of vacant site data replanted

Code
# Join the eco_summary with vacant_data based on the species (Common.Name)
vacant_eco <- vacant_data %>%
  left_join(eco_summary %>%
              select(!!sym(names(eco_summary)[1]), avg_benefit), # Select species and avg_benefit
            by = c("Common.Name" = names(eco_summary)[1])) %>%  # Join on species name
  mutate(!!sym(names(vacant_data)[5]) := avg_benefit)  # Replace the 5th column with avg_benefit

# Checked data, missing lat/long
vacant_eco <- vacant_eco %>%
  filter(Latitude != 0)

# View the updated vacant data with the avg_benefit in the 5th column
vacant_eco %>%
  head(5) %>%
  kable() %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
Editing Botanical.Name Common.Name DBH Total.Yearly.Eco.Benefits.... Stormwater.Benefits.... Stormwater.Gallons.Saved Greenhouse.CO2.Benefits.... CO2.Avoided..in.lbs.. CO2.Sequestered..in.lbs.. Energy.Benefits.... kWh.Saved Therms.Saved Air.Quality.Benefits.... Pollutants.Saved..in.lbs.. Property.Benefits.... Leaf.Surface.Area..in.sq..ft.. Address Street Side Site Council.District Park.Name Latitude Longitude Site.ID Location location avg_benefit
Buffalo VACANT MAPLE, SILVER 0 189.40818 0 0 0 0 0 0 0 0 0 0 0 0 250 Minnesota Av Front 1 University 0 42.94662 -78.82021 73961 (42.9466215137, -78.8202132436) POINT (-78.8202132436 42.9466215137) 189.40818
Buffalo VACANT MAPLE, CRIMSON KING 0 118.69964 0 0 0 0 0 0 0 0 0 0 0 0 722 Eggert Rd Side 1 University 0 42.94805 -78.80380 75828 (42.9480502373, -78.8037997246799) POINT (-78.8037997246799 42.9480502373) 118.69964
Buffalo VACANT OAK, SWAMP WHITE 0 73.51569 0 0 0 0 0 0 0 0 0 0 0 0 164 Rounds Av Front 1 University 0 42.94740 -78.80745 75879 (42.9474045086, -78.8074540366) POINT (-78.8074540366 42.9474045086) 73.51569
Buffalo VACANT MAPLE, NORWAY 0 132.88977 0 0 0 0 0 0 0 0 0 0 0 0 41 Rounds Av Front 1 University 0 42.94736 -78.81202 75922 (42.9473611754, -78.8120223129) POINT (-78.8120223129 42.9473611754) 132.88977
Buffalo VACANT MAPLE, CRIMSON KING 0 118.69964 0 0 0 0 0 0 0 0 0 0 0 0 559 Potomac Av Front 1 Delaware 0 42.92414 -78.87850 50106 (42.92413835322631, -78.87850124740001) POINT (-78.87850124740001 42.92413835322631) 118.69964

Total ecological benefit increase

Code
# Sum the total ecological benefit of vacant_eco
total_ecological_benefit <- sum(vacant_eco$avg_benefit, na.rm = TRUE)
total_ecological_benefit <- format(total_ecological_benefit, nsmall = 2, big.mark = ",", prefix = "$")

# Print the total ecological benefit
print(total_ecological_benefit)
[1] "7,573,792.78"

##Let’s map the new trees!

Code
vacant_eco_sf <- vacant_eco %>%
  st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326)  # Convert to sf object

# Use mapview to visualize
#map <- 
#mapview(vacant_eco_sf, zcol = "avg_benefit", legend = TRUE)

#mapshot(map, file = "eco_map.png")

Eco map of tree points

Conclusions

Interesting analyses from count and total ecological benefits alone. Although higher in overall count, crabapple and planetree are not in the highest ecological benefit categories. That section is dominated by maple species. From this analysis, assuming everyone who has a vacant slot plants a tree (distributed from top 15), by the time they reach maturity another 7,573,792.78 of ecological benefits could come from those 60,000 trees every year. However, that is with the assumption that all trees have the same average value, not accounting for trees of different ages or variation within species.

Unfortunately this webpage’s server is not powerful enough to display the 60,500 points of data (arguably a dataset too large to use for this project, in hindsight). The pre-rendered map graphic is from my personal computer, captured via screenshot. Due to the randomizing of tree assignment per vacant site, the projected ecological benefits are slightly altered but remain within the $7.6 million range. It would be interesting to continue this analysis for tree canopy coverage and localized (cooled) temperature data at street level across the city.

References

  • “Bureau of Forestry | Buffalo, NY.” n.d. Accessed December 2, 2024. https://www.buffalony.gov/358/Bureau-of-Forestry.

  • “Figure 4.-Urban Forest Species Composition as a Percentage of All…” n.d. ResearchGate. Accessed November 30, 2024. https://www.researchgate.net/figure/Urban-forest-species-composition-as-a-percentage-of-all-trees-Philadelphia-2012_fig3_321777064.

  • Holtz, Yan. n.d. “Dendrogram Customization with R and Ggraph.” Accessed November 30, 2024. https://www.r-graph-gallery.com/335-custom-ggraph-dendrogram.html.

  • “Tree Inventory | OpenData Buffalo.” n.d. Accessed December 2, 2024. https://data.buffalony.gov/Quality-of-Life/Tree-Inventory/n4ni-uuec/about_data.

  • Ziter, Carly D., Eric J. Pedersen, Christopher J. Kucharik, and Monica G. Turner. 2019. “Scale-Dependent Interactions between Tree Canopy Cover and Impervious Surfaces Reduce Daytime Urban Heat during Summer.” Proceedings of the National Academy of Sciences 116 (15): 7575–80. https://doi.org/10.1073/pnas.1817561116.