根据数据的列名,具有不同线条颜色和轨迹样式的线图 table

line plot with different line colors and trace style depending on column names of data table

我从服务器获得了一个数据 table dt.data,它可以具有以下列名称:

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)

数据 table 也可以有更少的列,例如某些产品被省略。然而,它也可以更长,例如每个产品不仅可以查看 2021 年,还可以查看 2022 年。此处的最后一列 "EEX FEUA MDEC1" 与日历年无关,在 table 中显示或不显示。

总共有 4 个不同的日历年是可能的,但并非所有 4 个都必须始终出现在 table 中,但仅限于 2021 年,如本例所示。

我想创建一个线图,为每个产品赋予特殊颜色,即:

"EEX DEB CAL-" 应该有颜色 "#007D3C"

"EEX ATB CAL-" 颜色应该是 "#81C07A"

"PEGAS TTF CAL-" 颜色应该是 "#F07D00"

"PEGAS NCG CAL-" 颜色应该是 "#FF9966"

"PEGAS AUTVTP CAL-" 颜色应该是 "#F7BEF7"

"ICE ATW CAL-" 颜色应该是 "#828282"

"ICE BRN CAL-" 应该有颜色 "#993333"

"EEX FEUA MDEC1" 颜色应该是 "#3399FF"

我还希望每个日历年都有不同的跟踪类型,例如"EEX DEB CAL-2021""EEX DEB CAL-2023" 仅在轨迹类型上有所不同,颜色应该相同 ("#007D3C")。由于最多有 4 个不同的日历年,我在下面的代码中定义了 line_type 如下: line_type <- setNames (c ("line", "dot", "dash", "lines + markers"), colNames).

我已经用下面的代码试过了:

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")) 

不幸的是,这个情节不起作用。

是否可以为产品分配某种颜色并设计这样的情节?由于 table 总是看起来不同,并且永远不会有相同的列,或者列可以以不同的顺序出现,所以我需要一个非常非常灵活和通用的图来显示我想要的内容。

最后,.

中已经给出了您所需要的一切

但是,我稍微更改了您的示例数据,以便您可以看到 dot 行。

你应该:

  1. 使用 melt.data.table
  2. 将您的数据从宽数据转换为长数据
  3. 使用有效的线型:'solid'、'dot'、'dash'、'longdash'、'dashdot'、'longdashdot'

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

作为替代方法,您可以删除命名的 linetypes 向量(参数 linetypes = linetypes)并让 plotly 自动选择线型