library(plotly)
library(dplyr)
library(scales)
dat <- readRDS("ridge_data.rds")
ridges <- dat$ridges; medians <- dat$medians
cols <- dat$cols; ord <- dat$order
SCALE_V <- 4.5
ymax <- 2026
pos <- function(y) ymax - y # 1990 at the top
gmax <- max(ridges$dens)
rgba <- function(hex, a) {
r <- col2rgb(hex); sprintf("rgba(%d,%d,%d,%s)", r[1], r[2], r[3], a)
}
p <- plot_ly()
shown <- setNames(rep(FALSE, length(ord)), ord)
for (yr in sort(unique(ridges$year))) {
for (sb in ord) {
r <- ridges %>% filter(suburb == sb, year == yr) %>% arrange(x)
if (nrow(r) == 0) next
base <- pos(yr)
p <- add_trace(p, type = "scatter", mode = "lines",
x = c(r$x, rev(r$x)),
y = c(base + r$dens / gmax * SCALE_V, rep(base, nrow(r))),
fill = "toself", fillcolor = rgba(cols[[sb]], 0.4),
line = list(color = cols[[sb]], width = 0.6),
legendgroup = sb, name = sb,
showlegend = !shown[[sb]], hoverinfo = "skip")
shown[[sb]] <- TRUE
}
}
for (sb in ord) {
m <- medians %>% filter(suburb == sb) %>% arrange(year)
p <- add_trace(p, type = "scatter", mode = "lines+markers",
x = m$median, y = pos(m$year),
line = list(color = cols[[sb]], width = 1.2),
marker = list(color = "white", size = 4,
line = list(color = cols[[sb]], width = 1)),
legendgroup = sb, showlegend = FALSE,
text = paste0(sb, "<br>", m$year, "<br>median ",
dollar(m$median, scale_cut = cut_short_scale()),
"<br>", comma(m$n), " sales"),
hovertemplate = "%{text}<extra></extra>")
}
yrs <- sort(unique(ridges$year))
layout(p,
title = list(
text = paste0("<b>Three Sydney suburbs, 1990 to 2026</b><br>",
"<sup>Yearly sale-price distribution; the solid line ",
"connects each year's median</sup>"),
x = 0, xanchor = "left", font = list(size = 16)),
xaxis = list(title = "Sale price", range = c(0, 3.2e6),
tickvals = c(0, 1e6, 2e6, 3e6),
ticktext = c("$0", "$1M", "$2M", "$3M"), zeroline = FALSE,
fixedrange = TRUE),
yaxis = list(title = "", tickvals = pos(yrs), ticktext = yrs,
showgrid = FALSE, zeroline = FALSE, fixedrange = TRUE),
dragmode = FALSE,
legend = list(groupclick = "togglegroup",
x = 0.99, xanchor = "right", y = 0.98, yanchor = "top",
bgcolor = "rgba(255,255,255,0.6)"),
hovermode = "closest", margin = list(l = 45, t = 70)) |>
plotly::config(displayModeBar = FALSE, responsive = TRUE,
scrollZoom = FALSE, doubleClick = FALSE)