I am trying to reproduce a graph generated via ggplotly with plot_ly. I am struggling however with the colorbar.
This is the ggploty plot that I would like to reproduce, and in particular the colorbar:
library(plotly)
X <- data.frame(w = rep(c("a", "b"), each = 8),
x = 1:16,
y = 1:16,
z = c(1, 1:13, 13, 13))
X$z_scaled <- (X$z-min(X$z))/(max(X$z)-min(X$z)) # scale to 0-1
# ggplot
gg <- ggplot(X) +
geom_point(aes(x, y, color = z_scaled, alpha = w, text = paste0(x, ", ", y))) +
scale_color_gradient2(low = '#0d71db', mid = "#dbc00d", high = '#db220d',
midpoint = .5, breaks = 0:1, limits = 0:1) +
scale_alpha_manual(name = " ", values = rep(1, nrow(X))) +
labs(color = "Z", x = "", y = "")
ggplotly(gg, type = "scattergl", tooltip = "text") %>% toWebGL()
This is what I have with plot_ly:
length_unique_vals <- length(unique(X$z))
.colors <- colorRampPalette(c('#0d71db', "#dbc00d", "#db220d"))(length_unique_vals)
.colors <- .colors[factor(X$z)]
plot_ly() %>%
add_markers(
data = X, x = ~x, y = ~y,
split = ~w,
text = ~paste0(x, ", ", y),
hoverinfo = "text",
type = "scattergl",
mode = "markers",
marker = list(
# color = ~z_scaled,
color = .colors,
# colorscale = list(c(0, .5, 1), c("#0d71db", "#dbc00d", "#db220d")),
colorscale = .colors,
hoverlabel = list(bgcolor = .colors),
colorbar = list(
title = list(text = "Z"),
len = .5,
x = 1,
y = .7
)
)
) %>%
layout(
legend = list(x = 1, y = .4, bgcolor = 'rgba(255,255,255,0.6)')
) %>% toWebGL() %>% partial_bundle(local = FALSE)
As you can see, the colorbar is not displaying correctly. I have tried multiple possibilities (commented above) without success. What am I missing?
Edit
@Kat's answer solves the colorbar issue. However, if you want to use scattergl or toWebGl you will need to fix the hoverlabel background so it remains dynamic. Here is a solution for that below building on her answer.
length_unique_vals <- length(unique(X$z))
.colors <- colorRampPalette(c('#0d71db', "#dbc00d", "#db220d"))(length_unique_vals)
.colors <- .colors[factor(X$z)]
plot_ly() %>%
add_trace(x = ~x,
y = ~y,
split = ~w, # instead of alpha or opacity
data = X,
type = "scattergl",
mode = "markers",
color = ~z_scaled, # color = var and colors = literal colors
colors = c('#0d71db', "#dbc00d", '#db220d'),
hoverlabel = list(bgcolor = .colors)) %>% # Fix hovercolor bg
layout(xaxis = list(title = "",
dtick = 4,
zeroline = F,
gridcolor = "white"), # white on gray
yaxis = list(title = "",
dtick = 4,
zeroline = F,
gridcolor = "white"), # white on gray
plot_bgcolor = "#eeeeee") %>% # gray background
colorbar(title = "Z", # colorbar title
dtick = c(0, 1), # colorbar ticks
thickness = 25) %>% # width
toWebGL() %>% partial_bundle(local = FALSE)
Edit 2
The hoverlabel bgcolor breaks down then the split factor is not ordered. This is why it needs to be ordered first.
library(plotly)
library(data.table)
X <- data.table(w = rep(c("a", "b"), 8), #not ordered
x = 1:16,
y = 1:16,
z = c(1, 1:13, 13, 13))
X[, z_scaled := (X$z-min(X$z))/(max(X$z)-min(X$z))] # scale to 0-1
# Get colors for hoverlabel bgcolor
X <- X[order(w)]
length_unique_vals <- length(unique(X$z))
.colors <- colorRampPalette(c('#0d71db', "#dbc00d", "#db220d"))(length_unique_vals)
.colors <- .colors[factor(X$z)]
plot_ly() %>%
add_trace(x = ~x,
y = ~y,
split = ~w, # instead of alpha or opacity
data = X,
type = "scattergl",
mode = "markers",
color = ~z_scaled, # color = var and colors = literal colors
colors = c('#0d71db', "#dbc00d", '#db220d'),
hoverlabel = list(bgcolor = .colors),
marker = list(size = 10)) %>% # Fix hovercolor bg
layout(xaxis = list(title = "",
dtick = 4,
zeroline = F,
gridcolor = "white"), # white on gray
yaxis = list(title = "",
dtick = 4,
zeroline = F,
gridcolor = "white"), # white on gray
plot_bgcolor = "#eeeeee") %>% # gray background
colorbar(title = "Z", # colorbar title
dtick = c(0, 1), # colorbar ticks
thickness = 25) %>% # width
toWebGL() %>% partial_bundle(local = FALSE)



