I am recreating the interactive plot from the plotly
example code below (found here) but I'm wondering if a long data.frame format can be used to avoid adding an individual add_trace
function for each variable in the legend. Similar to ggplot2
aesthetic layers.
Any interactive plotting solution would work (highcharter, plotly, etc.).
I also created an interactive stacked area chart from ggplotly
below, however the interactive functionality is not the same. Specifically, when layers are toggled on/off at the legend, they do not scale themselves so they are flat along the x-axis. They appear as is. For example, if colB is isolated it floats in the middle of the plot.
The plotly
example above does reset the layer and the user can visually inspect profiles of individual layers with a flat x-axis reference.
Thanks for any help.
library(plotly)
data <- t(USPersonalExpenditure)
data <- data.frame("year"=rownames(data), data)
p <- plot_ly(data, x = ~year, y = ~Food.and.Tobacco, name = 'Food and Tobacco', type = 'scatter', mode = 'none', stackgroup = 'one', fillcolor = '#F5FF8D') %>%
add_trace(y = ~Household.Operation, name = 'Household Operation', fillcolor = '#50CB86') %>%
add_trace(y = ~Medical.and.Health, name = 'Medical and Health', fillcolor = '#4C74C9') %>%
add_trace(y = ~Personal.Care, name = 'Personal Care', fillcolor = '#700961') %>%
add_trace(y = ~Private.Education, name = 'Private Education', fillcolor = '#312F44') %>%
layout(title = 'United States Personal Expenditures by Categories',
xaxis = list(title = "",
showgrid = FALSE),
yaxis = list(title = "Expenditures (in billions of dollars)",
showgrid = FALSE))
p
#
library(data.table)
library(magrittr)
library(ggplot2)
library(plotly)
library(lubridate)
dt <- data.table(colA = seq(from = ymd_hms("2020-01-01 00:00:00"),
to = ymd_hms("2020-01-01 00:00:00") + days(99),
by = "1 day"),
colB = runif(100,0,100),
colC = runif(100,0,100),
colD = runif(100,0,100)) %>%
melt(id.vars = "colA")
ggplot <- ggplot(data = dt) +
geom_area(aes(x = colA,
y = value,
fill = variable),
stat = "identity",
position = "stack",
alpha = 0.5) +
theme(legend.title = element_blank())
ggplot
ggplotly(ggplot)
The answer given by @s_t definitely works. But just for completeness I will add another way to accomplish this which may be cleaner.
You could also create a long data frame and use the split
argument in plot_ly
From the plot_ly documentation:
split: (Discrete) values used to create multiple traces (one trace per value).
This will probably do under the hood the same as @s_t option. But it is a little cleaner.
# create data frame in long format
data.long <- data %>% tidyr::pivot_longer(-year, names_to = "type", values_to = "value")
# create plot_ly using split argument to separate traces according to type
p <- plot_ly(data.long, x = ~year, y = ~value, type = 'scatter',
mode = 'none', stackgroup = 'one', split = ~type)
p