interactive-3d-maps.R
Code used to make the graph found within "Interactive 3D Maps"
library(plotly)
library(tidyverse)
library(dplyr)
library(stars)
earthquakes <- read_csv("earthquakes.csv")
degrees2radians <- function(degree) degree * pi / 180
earthquakes <- earthquakes |>
mutate(x=1.01 * cos(degrees2radians(longitude)) * cos(degrees2radians(latitude))) |>
mutate(y=1.01 * sin(degrees2radians(longitude)) * cos(degrees2radians(latitude))) |>
mutate(z=1.01 * sin(degrees2radians(latitude)))
manual_colorscale <- list(c(0,0.2,0.4,0.6,0.8,1),
c("white","#ffa590","#ff8164", "#ff6242","#fb4b1e","#c61a09"))
x_size <- 1000
y_size <- 500
raw_tif <- read_stars("surface.png",RasterIO = list(nBufXSize=x_size,nBufYSize=y_size))
rgb <- as.data.frame(raw_tif) |>
tidyr::pivot_wider(names_from = band, values_from = surface.png)
colnames(rgb)[3] <- "red"
colnames(rgb)[4] <- "green"
colnames(rgb)[5] <- "blue"
rgb$color <- rgb(rgb$red/255,rgb$green/255,rgb$blue/255)
rgb$color_int <- 256 * 256 * rgb$red + rgb$green * 256 + rgb$blue
rgb_earth <- matrix(data=rgb$color_int, nrow=y_size, ncol = x_size, byrow=TRUE)
lat <- seq(-90, 90, length.out = y_size)
lon <- seq(-180, 180, length.out = x_size)
lat <- matrix(rep(lat, x_size), nrow = y_size)
lon <- matrix(rep(lon, each = y_size), nrow = y_size)
earth_colorscale <- distinct(data.frame(rgb$color_int, rgb$color))
earth_colorscale <- earth_colorscale |> arrange(rgb.color_int)
while(nrow(earth_colorscale) > 255){
toDelete <- seq(0, nrow(earth_colorscale), 2)
earth_colorscale <- earth_colorscale[toDelete, ]
rownames(earth_colorscale) = NULL
}
earth_colorscale$breaks <- seq(1:nrow(earth_colorscale))/nrow(earth_colorscale)
earth_colorscale$breaks[1] = 0
earth_colorscale <- earth_colorscale[,c(3,2)]
names(earth_colorscale)[names(earth_colorscale) == 'rgb.color'] <- 'colors'
empty_axis <- list(
showgrid = FALSE,
zeroline = FALSE,
showticklabels = FALSE,
showspikes = FALSE,
spikesides = FALSE,
title = ""
)
image <- RCurl::base64Encode(readBin("size_scale.png", "raw", file.info("size_scale.png")[1, "size"]), "txt")
globe <- plot_ly(width=800,height=800) |>
add_sf(
data = sf::st_as_sf(maps::map("world", plot = FALSE, fill = TRUE)),
x = ~ 1.001 * cos(degrees2radians(x)) * cos(degrees2radians(y)),
y = ~ 1.001 * sin(degrees2radians(x)) * cos(degrees2radians(y)),
z = ~ 1.001 * sin(degrees2radians(y)),
color = I("black"), size = I(1),
hoverinfo = "none"
) |>
add_trace(
x=earthquakes$x,
y=earthquakes$y,
z=earthquakes$z,
mode = "markers", type = "scatter3d",
marker = list(color = earthquakes$magnitude, size = earthquakes$sig/100, colorscale = manual_colorscale, showscale=TRUE,
colorbar=list(title=list(text="Magnitude",side="top"), thickness=10, len=0.35, orientation='h', y=0.1,
tickfont=list(family="Arial"), nticks=6)),
text = paste0("Description: ", earthquakes$title, "<br>", "Time: ", earthquakes$date_time, "<br>" ,
"Magnitude: ", earthquakes$magnitude, "<br>", "Significance: ", earthquakes$sig),
hoverinfo = "text"
) |>
add_surface(
x = cos(degrees2radians(lon)) * cos(degrees2radians(lat)),
y = cos(degrees2radians(lat)) * sin(degrees2radians(lon)),
z = -sin(degrees2radians(lat)),
surfacecolor=rgb_earth,
colorscale=earth_colorscale,
showscale = FALSE,
hoverinfo = "none",
lightposition = list(
x=2,
y=2,
z=2
),
contours = list(
x = list(highlight = FALSE),
y = list(highlight = FALSE),
z = list(highlight = FALSE)
)
) |>
layout(
title=list(text="<br><b>Earthquakes Since 1995</b>",font=list(family="Arial", size=30)),
showlegend = FALSE,
annotations=list(text="Nikhil Chinchalkar For Princeton University | Seismic Research Dataset | 2024",
showarrow=FALSE, font=list(family="Arial", size=14), y=0),
images=list(list(source=paste('data:image/png;base64', image, sep=','),
xref="paper",
yref="paper",
x=0.5,
y=0.1,
sizex=.25,
sizey=.25,
xanchor="center",
yanchor="center")),
scene = list(
xaxis = empty_axis,
yaxis = empty_axis,
zaxis = empty_axis,
aspectratio = list(x = 1, y = 1, z = 1)
)
) |>
config(displayModeBar=FALSE)
globe
Last updated