Overlay Los Angeles Map over lat/long- HexHeatmap

Hi,

I am using a large Kaggle dataset California Traffic Collisions and I created a "Hex-Heatmap" based off the Latitude and Longitude and having the severity ranking from 5 through 1 (fatal to property damage) on the Z axis.

Obviously using the all the data for Los Angeles results in a better hex-map but below there is a random slice of 100 observations to exemplify what I'm trying to achieve on below reprex:

I thought it might be a little more instructive if I could see where the freeway are and maybe draw insight from that.

How do I add a map overlay of the city of Los Angeles to match the plot created on the reprex? The overlay has to match latitude and longitude so that the coloring makes sense.

library(tidyverse)
df <- tibble::tribble(
                                                         ~case_id,    ~collision_severity, ~latitude, ~longitude, ~severity_code,
                                                       "91075483", "property damage only",  34.07273, -117.78571,              1,
                                                       "91050981",                 "pain",  34.10287, -118.71098,              2,
                                                        "4268759", "property damage only",  33.90231, -118.26625,              1,
                                                       "90683402",                 "pain",  34.13534, -117.98468,              2,
                                                       "90057009", "property damage only",  34.06505, -117.80746,              1,
                                                        "5610743",                 "pain",  34.02234, -117.76681,              2,
                                                        "8811798", "property damage only",  34.04046, -117.96789,              1,
                                                       "90129212",                 "pain",   34.1183, -117.86479,              2,
                                                       "90399566", "property damage only",   34.0174, -118.17578,              1,
                                                       "90728716", "property damage only",  33.82387, -118.32841,              1,
                                                       "90487116", "property damage only",  34.03702, -118.31098,              1,
                                                       "90810851", "property damage only",  34.03968,  -118.2737,              1,
                                                       "91174344",                 "pain",  34.15945, -118.38032,              2,
                                                       "90227061",        "severe injury",  33.87688, -118.17416,              4,
                                                       "90438250", "property damage only",  33.98728, -118.06664,              1,
                                                       "90239743",                 "pain",  34.07072, -118.15439,              2,
                                                       "90663797", "property damage only",  33.97009, -118.08069,              1,
                                                        "9202515",        "severe injury",   33.9786, -118.19244,              4,
                                                        "6672852",                 "pain",  33.96706, -117.89429,              2,
                                                       "90194995",         "other injury",  34.21763, -118.47319,              3,
                                                       "90438280", "property damage only",   34.0717,  -118.0927,              1,
                                                        "3951829",                 "pain",  34.06408, -117.80552,              2,
                                                        "8888887", "property damage only",  33.88081, -118.30913,              1,
                                                        "4759471", "property damage only",   34.0554,  -118.1954,              1,
                                                        "4821346", "property damage only",  34.00597, -117.96699,              1,
                                                       "90440008", "property damage only",  34.05375, -118.23691,              1,
                                                       "90477260",                 "pain",   34.1568, -118.44845,              2,
                                                        "5463311",                 "pain",  33.87289, -118.27781,              2,
                                                       "90913060",         "other injury",  33.92835, -118.02909,              3,
                                                        "6900209",         "other injury",  33.98163, -117.96158,              3,
                                                       "90247843", "property damage only",  33.87633, -118.08413,              1,
                                                        "5169678", "property damage only",  34.03369, -118.15235,              1,
                                                        "6471999", "property damage only",  33.94392, -118.17098,              1,
                                                       "90685142", "property damage only",  34.00856, -118.15828,              1,
                                                        "4357081",                 "pain",   34.0942,   -118.244,              2,
                                                        "8723792", "property damage only",  34.13791, -117.98014,              1,
                                                        "6644461", "property damage only",  33.99267, -117.90549,              1,
                                                       "90877411", "property damage only",  33.91777, -118.03438,              1,
                                                       "91087485",                 "pain",  33.96735, -118.08315,              2,
                                                        "5136000",                 "pain",  34.03536, -118.33183,              2,
                                                       "90312908", "property damage only",  34.02245, -118.27759,              1,
                                                        "5491007", "property damage only",  33.98114, -117.97189,              1,
                                                        "4415496", "property damage only",  33.85965, -118.29943,              1,
                                                       "91352272", "property damage only",  34.15625, -118.25749,              1,
                                                        "6961892", "property damage only",  34.15293, -118.28294,              1,
                                                       "90992686", "property damage only",  33.51276, -118.12834,              1,
                                                        "4553655", "property damage only",  33.87395,  -118.2023,              1,
                                                        "5574989", "property damage only",  34.16037, -118.46603,              1,
                                                       "90066424",                 "pain",  34.02542, -117.80591,              2,
                                                       "90914526", "property damage only",  34.03511, -118.32873,              1,
                                                       "90655202", "property damage only",  34.01683, -118.28074,              1,
                                                        "6754208",                 "pain",  34.05538, -118.19652,              2,
                                                       "90041989",                 "pain",  34.03047, -118.17165,              2,
                                                        "4552519", "property damage only",  33.75797, -118.28994,              1,
                                                       "90807064", "property damage only",  34.01604, -118.42176,              1,
                                                        "6352776", "property damage only",  34.08809, -118.23576,              1,
                                                        "3940139", "property damage only",  34.54914, -118.43196,              1,
                                                       "91285858", "property damage only",  34.09276, -117.99068,              1,
                                                        "6115945", "property damage only",  34.00169, -117.83608,              1,
                                                        "6926743", "property damage only",  34.12175, -118.27193,              1,
                                                        "6120493", "property damage only",  34.02845, -118.44782,              1,
                                                       "90052888",         "other injury",   33.9745,  -118.3822,              3,
                                                        "6911684", "property damage only",  34.16893,  -118.5925,              1,
                                                        "6631999", "property damage only",  34.15101, -118.28101,              1,
                                                        "6336072", "property damage only",  34.02589, -118.46325,              1,
                                                        "5029249", "property damage only",  34.02479, -118.20371,              1,
                                                        "5266332", "property damage only",  34.07257,  -117.7859,              1,
                                                       "91128223", "property damage only",  34.14828, -118.80486,              1,
                                                       "91162356", "property damage only",  33.99266, -118.28038,              1,
                                                        "4129006",                 "pain",  33.99409, -117.88921,              2,
                                                       "90263576",         "other injury",   33.8756,  -118.1048,              3,
                                                        "6497903", "property damage only",  33.87604, -118.10286,              1,
                                                        "4959877", "property damage only",  34.22079,  -118.2442,              1,
                                                       "90145217",         "other injury",  34.00116, -117.83991,              3,
                                                        "6794348",                 "pain",  34.04095, -118.21865,              2,
                                                       "91209455", "property damage only",  34.06935, -117.79739,              1,
                                                       "90292058", "property damage only",  34.13213, -117.95026,              1,
                                                        "6029093", "property damage only",  33.99383, -118.17625,              1,
                                                       "90096628",                 "pain",  34.00401, -117.95436,              2,
                                                        "6059606",                 "pain",  34.17238, -118.57007,              2,
                                                        "3984977",         "other injury",  34.20277, -118.47364,              3,
                                                        "6951505", "property damage only",  33.88611, -118.19037,              1,
                                                        "4883145", "property damage only",  33.00546, -117.09516,              1,
                                                       "90977585", "property damage only",  34.04817, -118.44753,              1,
                                                       "91058783", "property damage only",  34.20517, -118.21724,              1,
                                                        "5293230", "property damage only",  34.09732, -118.24619,              1,
                                                        "4516652", "property damage only",  34.06659, -117.99151,              1,
                                                        "4690952", "property damage only",  34.02466, -117.76372,              1,
                                                        "4381461", "property damage only",  34.38225, -118.56718,              1,
                                                        "5144298",         "other injury",  34.01905, -118.48011,              3,
                                                       "90887119", "property damage only",  34.07637, -118.46947,              1,
                                                        "6941283",                 "pain",    33.883,  -118.3528,              2,
                                                       "90690911", "property damage only",  34.01446, -118.16013,              1,
                                                        "5507978", "property damage only",  34.08493,  -117.9969,              1,
                                                       "90831118", "property damage only",   34.0257,  -118.4653,              1,
                                                       "90047442", "property damage only",   33.9305, -118.36813,              1,
                                                        "6038385",         "other injury",  34.02738, -117.96475,              3,
                                                        "4222205",                 "pain",  34.15584, -118.43532,              2,
                                                       "90343665", "property damage only",  34.04013, -118.16961,              1,
                                                        "5530254", "property damage only",  34.00419, -118.39346,              1
                                                       )




df %>% ggplot(aes(longitude, latitude, z = severity_code)) +
  stat_summary_hex(alpha = 0.8, bins = 65) + theme_minimal() +
  scale_fill_viridis_c() +
  theme(plot.title = element_text(size = 9),
        legend.title = element_text(size = 8),
        legend.position="bottom") +
  labs(
    fill = "Severity (5- Fatal,4- Sever Injury, 3- Other Injury, 2- Pain, 1 - Property Dmg Only)",
    title = "Lat. & Long.vs Severity Hex-Heatmap"
  )

Created on 2021-11-23 by the reprex package (v2.0.1)

  • Smaller issue is how to have the legend title be positioned above the legend (set to bottom)

Any help is much appreciated.

I recommend the {sf} package, which provides facilities to create geometries of polygons, such as LA city or county in data frame like form in which point data in the form of severity:long:lat can be added. Then it's just normal {ggplot2} layering.