Skip to content

Commit 4bef904

Browse files
committed
3D globe with storm paths example
1 parent 87ba6a8 commit 4bef904

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

demo/00Index

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ sf-mapbox-layout Mapping sf objects with mapbox (as a layer
2020
sf-ggplot2 Mapping sf objects via ggplot2 and geom_sf()
2121
sf-geo Mapping sf objects with scattergeo
2222
sf-plotly-storms Visualizing sf objects with >2 coordinates (e.g. altitude)
23+
sf-plotly-3D-globe Visualizing storms paths on a 3D globe

demo/sf-plotly-3D-globe.R

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
library(plotly)
2+
3+
storms <- sf::st_read(system.file("shape/storms_xyz.shp", package = "sf"), quiet = TRUE)
4+
5+
empty_axis <- list(
6+
showgrid = FALSE,
7+
zeroline = FALSE,
8+
showticklabels = FALSE,
9+
title = ""
10+
)
11+
12+
# even grid of lat/lons along the whole globe
13+
nlat <- 200
14+
nlon <- 100
15+
lat <- seq(-180, 180, length.out = nlat)
16+
lon <- seq(-90, 90, length.out = nlon)
17+
lat <- matrix(rep(lat, nlon), nrow = nlat)
18+
lon <- matrix(rep(lon, each = nlat), nrow = nlat)
19+
20+
# helper function for converting polar -> cartesian
21+
degrees2radians <- function(degree) degree * pi / 180
22+
23+
plot_ly() %>%
24+
add_sf(
25+
data = sf::st_as_sf(maps::map("world", plot = FALSE, fill = TRUE)),
26+
x = ~ 1.001 * cos(degrees2radians(x)) * cos(degrees2radians(y)),
27+
y = ~ 1.001 * sin(degrees2radians(x)) * cos(degrees2radians(y)),
28+
z = ~ 1.001 * sin(degrees2radians(y)),
29+
color = I("black"), hoverinfo = "none", size = I(1),
30+
showlegend = FALSE
31+
) %>%
32+
add_sf(
33+
data = storms,
34+
name = "storm paths",
35+
x = ~ cos(degrees2radians(x)) * cos(degrees2radians(y)),
36+
y = ~ sin(degrees2radians(x)) * cos(degrees2radians(y)),
37+
# TODO: this is just a guess, the rescaling range is not actually [0, 0.2]...
38+
z = ~ sin(degrees2radians(y)) + scales::rescale(z, to = c(0, 0.2))
39+
) %>%
40+
add_surface(
41+
x = cos(degrees2radians(lon)) * cos(degrees2radians(lat)),
42+
y = sin(degrees2radians(lon)) * cos(degrees2radians(lat)),
43+
z = sin(degrees2radians(lat)),
44+
# TODO: perhaps there is a better way to specify a constant surfacecolor?
45+
surfacecolor = matrix(rep(0.5, nlat * nlon), nrow = nlat),
46+
colorscale = data.frame(c(0, 0.5, 1), c("red", "white", "blue")),
47+
showscale = FALSE,
48+
hoverinfo = "none"
49+
) %>%
50+
# TODO: is there a way to turn on the spikelines?
51+
layout(
52+
scene = list(
53+
xaxis = empty_axis,
54+
yaxis = empty_axis,
55+
zaxis = empty_axis,
56+
aspectratio = list(x = 1, y = 1, z = 1),
57+
camera = list(eye = list(x = .41, y = -.71, z = 0.57))
58+
)
59+
)
60+

0 commit comments

Comments
 (0)