1

For the visualization of my predictive models on electric vehicle charging demand I would like to create heatmaps showing the hotspots of charging demand across multiple cities. I would like to use two different types of heatmaps - contour heatmaps and density heatmaps spread over the map in hexagons (I split my data into hexagonal cells for prediction).

Unfortunately I only managed to create heatmaps with counts but not the actual (charging demand) values. I tried spitting/cutting the data, made sure that only observations > 0 were used and tried to limit the x/y axis - nothing has worked so far. I hope someone here has a nifty idea on how to do this. Below a piece of sample data and both heatmap codes that now produce count-heatmaps instead of value-heatmaps (lon/lat are the centroids of my hexagonal cells into which the data is aggregated):

+---+------------+-------------+----------------+
|   |     lon    |      lat    |charging_demand |
+---+------------+-------------+----------------+
| 1 | 12.65783   | 55.58421    |     653.7      |
| 2 | 12.67671   | 55.59255    |     24.1       |
| 3 | 12.66813   | 55.59422    |     376.2      |
+---+------------+-------------+----------------+

For quick replication:

 df.data <- data.frame(lon = c(12.64753, 12.64924, 12.55998, 12.51878, 12.52221, 12.58401, 12.55655, 12.57371, 12.59088, 12.58058),
                      lat = c(55.63091, 55.62924, 55.67594, 55.78267, 55.78601, 55.68261, 55.66593, 55.67927, 55.67927, 55.70596),
                      charging_demand = c(663.7, 627.4, 597.4, 14.5, 396.3, 300.0, 0.00, 256.9, 228.5, 0.2))

Hexagonal heatmap (count) example:

 map <- get_map(location = "Copenhagen", zoom = 12)

 ggmap(map) + 
  coord_cartesian() + 
  geom_hex(data = df.data, aes(x = lon, y = lat, colour = charging_demand), 
           alpha = 0.6, color = "black", show.legend = TRUE, stat = "binhex") +
  guides(fill = FALSE, alpha = FALSE) +
  scale_fill_gradientn (colours = c("green","red"))

Contour heatmap (count) example:

 ggmap(map, extent = "device") + 
  geom_density2d(data = df.data, aes(x = lon, y = lat), size = 0.3) + 
  stat_density2d(data = df.data, aes(x = lon, y = lat, fill = ..level.., alpha = ..level..), 
                 size = 0.01, bins = 10, geom = "polygon") + 
  scale_fill_gradient(low = "green", high = "red") + 
  scale_alpha(range = c(0, 0.3), guide = FALSE)

Cutting the data even into 1000 pieces didn't help either:

 df.data$demand_cut <- cut(df.data$charging_demand, breaks = 1000)
Jonathan
  • 148
  • 1
  • 10
  • `geom_point` with `colour` aesthetic set to be `charging_demand` could be more suitable if you want to plot the actual value but not count. – www Jun 06 '17 at 21:01
  • Is there any way I could then get that to be "inside" my hexagons? Plotting 3000 individual points on a map does not look very professional after all. – Jonathan Jun 06 '17 at 21:21
  • Perhaps calculating the mean of `charging_demand` for each hexagon, then plot the mean. – www Jun 06 '17 at 21:27
  • I already have the mean (I aggregated per month and then only saved the mean). How would I be able to fill the hexagon with the mean? Or the contour heatmap? – Jonathan Jun 06 '17 at 21:34
  • If you are working with summary data already, you can plot the mean as points. The total number of points is probably less than 3000. The other idea is look at this thread (https://stackoverflow.com/questions/16894460/mapping-variable-to-hexagon-size-with-geom-hex) to see if there are any workaround. – www Jun 06 '17 at 21:51
  • And just to be clear, when I am talking about mean, I am talking about the mean within a spatial extent. Not the mean across the time. My idea is perhaps you can aggregate the data by longitude and latitude and calculate the mean. – www Jun 06 '17 at 21:55
  • Yeah - it's all aggregated to the cell level already, no issues there. However, if I use `ggplot(df.data, aes(x=lon, y=lat, col=charging_demand_mean)) + geom_hex()`, everything looks good, the charging demand values are aggregated into the hexagons. When I want to plot this on a map though `ggmap(map, extent = "device", base_layer = ggplot(df.data, aes(x=lon, y=lat, col=charging_demand_mean))) + coord_cartesian() + geom_hex(stat="binhex")` the hexbin package automatically starts counting the observations per hexagon and ignores the previous aggregation of charging demand... – Jonathan Jun 06 '17 at 23:05
  • 2
    Use `geom_hex(stat = "identity", aes(fill = charging_demand_mean))` – Brian Jun 06 '17 at 23:55

0 Answers0