I am trying to create a graph using plot_ly that looks something like this (i.e. there is a stacked plot over the top of an unstacked plot). FYI the numbers above the bars are not relevant for this.
I want separate layouts for each trace but when I run this it seems that the layout is global rather than separate per trace:
plot_ly()%>%
add_trace(data = data1, x = ~From, y = ~Value, type = "bar", color=~To) %>%
layout(barmode = "stack") %>%
add_trace(data = data2, x = ~From, y = ~total_value, type = "bar") %>%
layout(barmode = "overlay")
Is it possible to do this or is there a workaround?
Here is the data to play with:
data1=structure(list(From = structure(c(2L, 5L, 6L, 7L, 1L, 3L, 4L, 7L, 8L, 2L, 4L, 5L, 6L, 7L, 8L, 2L, 3L, 5L, 7L, 1L, 3L, 4L, 8L, 1L, 3L, 1L, 2L, 3L, 4L, 8L, 2L, 3L, 5L, 7L, 2L, 5L, 6L, 7L, 3L, 4L, 7L, 8L, 4L, 5L, 6L, 7L, 8L, 2L, 3L, 5L, 7L, 1L, 3L, 4L, 8L, 1L, 3L, 1L, 2L, 3L, 4L, 8L, 2L, 3L, 5L, 7L, 2L, 5L, 6L, 7L, 3L, 4L, 7L, 8L, 4L, 5L, 6L, 7L, 8L, 2L, 3L, 5L, 7L, 3L, 4L, 8L, 1L, 3L, 1L, 2L, 3L, 4L, 8L, 2L, 3L, 5L, 7L), levels = c("Lucy", "Jimmy", "Luke", "Paul", "Sarah", "David", "Farms", "Iain"), class = "factor"),
To = c("Lucy", "Lucy", "Lucy", "Lucy", "Jimmy", "Jimmy",
"Jimmy", "Jimmy", "Jimmy", "Luke", "Luke", "Luke", "Luke",
"Luke", "Luke", "Paul", "Paul", "Paul", "Paul", "Sarah",
"Sarah", "Sarah", "Sarah", "David", "David", "Farms", "Farms",
"Farms", "Farms", "Farms", "Iain", "Iain", "Iain", "Iain",
"Lucy", "Lucy", "Lucy", "Lucy", "Jimmy", "Jimmy", "Jimmy",
"Jimmy", "Luke", "Luke", "Luke", "Luke", "Luke", "Paul",
"Paul", "Paul", "Paul", "Sarah", "Sarah", "Sarah", "Sarah",
"David", "David", "Farms", "Farms", "Farms", "Farms", "Farms",
"Iain", "Iain", "Iain", "Iain", "Lucy", "Lucy", "Lucy", "Lucy",
"Jimmy", "Jimmy", "Jimmy", "Jimmy", "Luke", "Luke", "Luke",
"Luke", "Luke", "Paul", "Paul", "Paul", "Paul", "Sarah",
"Sarah", "Sarah", "David", "David", "Farms", "Farms", "Farms",
"Farms", "Farms", "Iain", "Iain", "Iain", "Iain"), Value = c(10,
10, 20, 10, 10, 10, 10, 20, 10, 10, 10, 20, 10, 10, 10, 10,
10, 10, 10, 10, 20, 10, 10, 20, 10, 10, 20, 10, 10, 10, 10,
10, 10, 10, 10, 10, 20, 10, 10, 10, 20, 10, 10, 20, 10, 10,
10, 10, 10, 10, 10, 10, 20, 10, 10, 20, 10, 10, 20, 10, 10,
10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 20, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 20, 10, 10, 20, 10,
10, 10, 10, 10, 10, 10)), row.names = c(NA, -97L), class = c("tbl_df", "tbl", "data.frame"))
data2=structure(list(From = structure(1:8, levels = c("Lucy", "Jimmy", "Luke", "Paul", "Sarah", "David", "Farms", "Iain"), class = "factor"),
total_value = c(50, 50, 60, 40, 50, 30, 60, 40)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -8L))
You can construct your plot as a ggplot2
object before calling ggplotly()
.
library(ggplot2)
library(plotly)
library(dplyr)
data1_sum <- data1 |> summarize(
Value = sum(Value), .by = c(From, To)
)
p1 <- data2 |>
ggplot(aes(x = From)) +
geom_col(aes(y = total_value, fill = From)) +
geom_col(data = data1_sum,
aes(y = Value, fill = To),
width = 0.3) +
scale_fill_brewer(palette = 'Dark2')
p1
# Commented out for reprex
# ggplotly(p1)
Created on 2024-06-24 with reprex v2.1.0