I get a data table dt.data
from a server that can have the following column names:
set.seed(123)
dt.data <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
'EEX DEB CAL-2021' = rnorm(365, 2, 1), 'EEX ATB CAL-2021' = rnorm(365, 4, 2),
'PEGAS TTF CAL-2021' = rnorm(365, 2, 2), 'PEGAS NCG CAL-2021' = rnorm(365, 4, 3),
'PEGAS AUTVTP CAL-2021' = rnorm(365, 1, 2), 'ICE ATW CAL-2021' = rnorm(365, 3, 2),
'ICE BRN CAL-2021' = rnorm(365, 2, 1), 'EEX FEUA MDEC1' = rnorm(365, 2, 2),
check.names = FALSE)
The data table can also have fewer columns if, e.g. certain products are omitted. However, it can also be longer if, e.g. not only the year 2021 but also 2022 is viewed for each product. The last column here "EEX FEUA MDEC1"
is independent of the calendar year and is either presented in the table or not.
A total of 4 different calendar years are possible, but not all 4 must always be present in the table, but only in 2021, as in this case.
I want to create a line plot that gives each product a special color, namely:
"EEX DEB CAL-"
should have the color "#007D3C"
"EEX ATB CAL-"
should have the color "#81C07A"
"PEGAS TTF CAL-"
should have the color "#F07D00"
"PEGAS NCG CAL-"
should have the color "#FF9966"
"PEGAS AUTVTP CAL-"
should have the color "#F7BEF7"
"ICE ATW CAL-"
should have the color "#828282"
"ICE BRN CAL-"
should have the color "#993333"
"EEX FEUA MDEC1"
should have the color "#3399FF"
I would also like to have a different trace type for each calendar year, whereby, e.g. "EEX DEB CAL-2021"
and "EEX DEB CAL-2023"
only differ in the trace type and should still have the same color ("#007D3C"
). Since there are a maximum of 4 different calendar years, I have defined line_type
in the code below as following:
line_type <- setNames (c ("line", "dot", "dash", "lines + markers"), colNames)
.
I have already tried it with this code below:
colNames <- names(dt.data)[-1]
colors <- setNames(c("#007D3C", "#81C07A", "#F07D00", "#FF9966", "#F7BE7F", "#828282",
"993333", "#3399FF"), colNames)
line_type <- setNames(c("line", "dot", "dash","lines+markers"), colNames)
p <- plotly::plot_ly()
for(trace in colNames){
p <- p %>% plotly::add_trace(data = dt.data, x = ~date, y = as.formula(paste0("~`", trace, "`")), name = trace,
type = 'scatter', mode = 'lines', connectgaps = TRUE,
hovertemplate = paste("%{xaxis.title.text}: %{x}<br>",
"%{yaxis.title.text}: %{y}<br>"),
line = list(color = colors[[trace]], dash = line_type[[trace]]))
}
p %>%
layout(title = "Info",
xaxis = list(title = "Date"),
yaxis = list (title = "\u20ac/MWh"))
Unfortunately this plot doesn't work.
Is it possible to assign a certain color to a product and design this plot like that? Since the table always looks different and never has the same columns or the columns can appear in different order, I need a very, very flexible and general plot that shows me what I want to have.
In the end, all you need for this was already given in this answer.
However, I changed your example data a little so you can see the dot
line.
You should:
melt.data.table
library(data.table)
library(plotly)
set.seed(123)
dt.data <-
data.table(
date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
'EEX DEB CAL-2021' = rnorm(365, 2, 1),
'EEX ATB CAL-2021' = rnorm(365, 4, 2),
'EEX DEB CAL-2023' = rnorm(365, 2, 1),
'EEX ATB CAL-2023' = rnorm(365, 4, 2),
'PEGAS TTF CAL-2021' = rnorm(365, 2, 2),
'PEGAS NCG CAL-2021' = rnorm(365, 4, 3),
'PEGAS AUTVTP CAL-2021' = rnorm(365, 1, 2),
'ICE ATW CAL-2021' = rnorm(365, 3, 2),
'ICE BRN CAL-2021' = rnorm(365, 2, 1),
'EEX FEUA MDEC1' = rnorm(365, 2, 2),
check.names = FALSE
)
DT <- melt.data.table(dt.data, id.vars = "date")
DT[, c("product_name", "calendar_year") := tstrsplit(variable, "-")]
DT[, "calendar_year" := lapply(.SD, function(x){ifelse(is.na(x),"none",x)}), .SDcols = "calendar_year"]
product_names <- c("EEX DEB CAL", "EEX ATB CAL", "PEGAS TTF CAL", "PEGAS NCG CAL", "PEGAS AUTVTP CAL", "ICE ATW CAL", "ICE BRN CAL", "EEX FEUA MDEC1")
colors <- setNames(c("#007D3C", "#81C07A", "#F07D00", "#FF9966", "#F7BE7F", "#828282",
"993333", "#3399FF"), product_names)
# Valid linetypes include: 'solid', 'dot', 'dash', 'longdash', 'dashdot', 'longdashdot'
calendar_years <- unique(DT$calendar_year)
linetypes <- setNames(c('solid', 'dot', 'dash', 'longdash', 'dashdot', 'longdashdot'), calendar_years)
p <- plot_ly(DT, x = ~ date, y = ~ value, color = ~ product_name, name = ~ variable, colors = colors, type = 'scatter', mode = 'lines', linetype = ~ calendar_year, linetypes = linetypes,
connectgaps = TRUE,
hovertemplate = paste("%{xaxis.title.text}: %{x}<br>",
"%{yaxis.title.text}: %{y}<br>")) %>%
layout(title = "Info",
xaxis = list(title = "Date"),
yaxis = list (title = "\u20ac/MWh"))
p
As an alternative approach you could drop the named linetypes
vector (argument linetypes = linetypes
) and let plotly choose the linetypes automatically