【问题标题】:line plot with different line colors and trace style depending on column names of data table根据数据表的列名具有不同线条颜色和轨迹样式的线图
【发布时间】:2021-02-05 04:40:15
【问题描述】:

我从可以具有以下列名称的服务器获取数据表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)

数据表也可以有更少的列,例如,某些产品被省略。但是,如果,例如,它也可以更长。每个产品不仅可以查看 2021 年,还可以查看 2022 年。这里的最后一列"EEX FEUA MDEC1" 与日历年无关,要么显示在表格中,要么不显示。

总共可能有 4 个不同的日历年,但并非所有 4 个日历年都必须始终出现在表格中,而仅在 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 &lt;- 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")) 

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

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

【问题讨论】:

  • EEX DEB CAL-2023 在您提供的数据中不存在。
  • 不在此数据表中,但服务器可能不仅提供 2021 年的产品,还提供 2023 年的产品。然后该表将有 7 个附加列。 dt.data 只是一个示例数据表,但它包含所有可能的产品(不考虑年份)。
  • 当然,但为了测试,最好有一个包含可变线型的代表性数据集(基于日历年)。
  • EEX FEUA MDEC1 没有指定年份
  • 作为旁注 - 请使用r-plotly 标记来解决有关 R 的 plotly API 的问题。

标签: r plotly trace r-plotly line-plot


【解决方案1】:

最后,this answer 中已经提供了您所需的一切。

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

你应该:

  1. 使用melt.data.table将数据从宽转换为长
  2. 使用有效的线型:'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 自动选择线型

【讨论】:

  • 在您的版本中,未绘制其他行(产品)。我需要上面代码中的 for 循环吗?另外"EEX DEB CAL-2021""EEX DEB CAL-2023"应该是同色的。
  • 它们被绘制了,我只是取消选择它们以避免混淆。我会更新颜色。
  • 不,这不起作用,因为它只绘制EEX FEUA MDEC1
  • 跟踪应该用....CAL-2021命名,不能没有hypchen -。我该怎么做?
  • 这是通过 name 参数完成的 - 刚刚再次更新。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 2019-07-24
  • 2020-05-21
  • 2016-09-15
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多