library(ggplot2)
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks plotly::filter(), stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(sf)
## Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
#dataset used
#?USArrests

#add column with states
USArrests <- cbind(States = rownames(USArrests), USArrests)
#remove original [1] column
rownames(USArrests) <- NULL

#add state code column
USArrestsCode <- USArrests %>%
  mutate(code = c("AL", "AK",   "AZ",   "AR",   "CA",   "CO",   "CT",   "DE",   "FL",   "GA",   
                  "HI", "ID",   "IL",   "IN",   "IA",   "KS",   "KY",   "LA",   "ME",   "MD",   "MA",   
                  "MI", "MN",   "MS",   "MO",   "MT",   "NE",   "NV",   "NH",   "NJ",   "NM",   "NY",   
                  "NC", "ND",   "OH",   "OK",   "OR",   "PA",   "RI",   "SC",   "SD",   "TN",   
                  "TX", "UT",   "VT",   "VA",   "WA",   "WV",   "WI",   "WY"))

#add total crime column 
USArrestsTotal <- USArrestsCode %>% mutate(TotalCrime = rowSums(across(c(Murder, Assault, Rape))))
USArrestsTotal
#add hover details to column
USArrestsTotal$hover <- with(USArrestsTotal, paste(States, '<br>', "Urban Population (%):", UrbanPop,'<br>', "Murder cases:", Murder,'<br>', "Assault cases:", Assault,'<br>', "Rape cases:", Rape))

# give state boundaries a white border
l <- list(color = toRGB("white"), width = 2)

#font specifications
tf <- list(
  family = "Arial",
  size = 25,
  color = "black"
)

lf <- list(
  family = "Arial",
  size = 20,
  color = "black"
)

# specify some map projection/options
USAPlot <- list(
  scope = 'usa',
  projection = list(type = 'albers usa'),
  showlakes = TRUE,
  lakecolor = toRGB('white')
)

g <- list(
  scope = 'usa',
  projection = list(type = 'albers usa'),
  lakecolor = toRGB('white')
)

m <- list(
  l = 50,
  r = 50,
  b = 100,
  t = 100,
  pad = 4
)

plot_ly(USArrestsTotal) %>%
  layout(geo = g) %>%
  add_trace(type = "choropleth", locationmode = 'USA-states',
            locations = ~code,
            z = ~TotalCrime, text = ~hover,
            color = ~TotalCrime, colors = 'Greens',
            name = " ") %>%
  add_trace(type = "scattergeo", locationmode = 'USA-states',
            locations = ~code, text = paste0("<b>", USArrestsTotal$code, "\n", USArrestsTotal$TotalCrime, "</b>"),
            mode = "text",
            textfont = list(color = rgb(0,0,0), size = 7.5),
            hoverinfo = 'skip') %>% 
  colorbar(title = "Number of crime cases per 100,000 persons", font = lf) %>% 
  layout(title = list(text = "How safe is your state? <br> (Hover for breakdown)", y = 0.9, x= 0.3, font = tf),
         geo = USAPlot) %>% 
  layout(autosize = F, width = 1050, height = 1050, margin = m)
## Warning: Specifying width/height in layout() is now deprecated.
## Please specify in ggplotly() or plot_ly()