如何在 r 中制作两个过滤器以绘图方式切换图表线条的可见性?我如何在过滤器中使用 multi-select?
How do I make two filters in r plotly toggle visibility of lines of a chart? How do I multi-select in the filters?
我正在尝试使用 R plot_ly 创建折线图,可以使用沿“产品”和“Chip_type”过滤的过滤器按钮打开和关闭折线图。
这个想法是供应商(“供应商”/“Supplier_text”)每月(“日期”)为公司的不同产品部门(“产品”)供应不同种类的芯片(“Chip_type”) .为了了解顶级供应商的概况,我想为每个供应商画一条线,图例中显示“Supplier_text”,图例条目按显示在“[”前面的 abs(number) 降序排序=67=]”。在这方面,数据 tibble 被正确排序。
“总体”条目是指该产品的所有供应商的总和。
可在 post 的末尾找到完整的数据集。
sample from dat :
Date(chr) Supplier Supplier_text order(int) Chip_type Product n(chr)
1 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Micro Smartphones 106
2 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Nano Smartphones 16920
3 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 BiMech Smartphones 61216
4 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Titan Smartphones 363698
5 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Quantum Smartphones 50797
6 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Platinum Smartphones 52715
7 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 PlainChip Smartphones 174342
8 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Classic Smartphones 9319
9 2019-12 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Micro Smartphones 92
10 2019-12 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Nano Smartphones 16928
11 2019-12 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 BiMech Smartphones 40920
17 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Micro Monitors 3
18 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Nano Monitors 1536
19 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 BiMech Monitors 6793
20 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Titan Monitors 45146
21 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Quantum Monitors 7922
22 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Platinum Monitors 5359
23 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 PlainChip Monitors 27390
24 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Classic Monitors 1131
25 2019-12 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Micro Monitors 12
33 2019-11 A -17385 | -88.0% - A 3 Titan Smartphones 3619
34 2019-11 A -17385 | -88.0% - A 3 Platinum Smartphones 13
35 2019-11 A -17385 | -88.0% - A 3 Quantum Smartphones 2
为了保持顺序(稍后能够切换正确的行!)我正在循环添加跟踪到一个空的 plot_ly 对象,如下所示:
library(stringr)
library(dplyr)
library(plotly)
# "Rebuilding" the data frame as the loop runs to see if what the loop does to the traces ends up being the same (order) as the original data frame. For that, I create an empty object first:
dat_plotly_object_copy = c()
plotly_object <- plot_ly()
id = 1
# I loop along "order", which marks all data of a single supplier:
for(id in 1:max(dat$order)){
dat_one_supplier <- filter(dat, order == id)
plotly_object <- plotly_object %>% add_trace(., data = dat_one_supplier,
# I filter the data set by supplier, to be able to create a line along the dates (~x) per supplier (~Supplier_text) and Chip_type (~n):
x = ~Date,
y = ~n,
color = ~Supplier_text,
type = "scatter",
mode = "lines")
dat_plotly_object_copy <- dat_plotly_object_copy %>%
rbind(.,dat_one_supplier)
}
identical(dat, dat_plotly_object_copy)
# The created data frame seems to be identical to what the loop does - so the order should match (?)
使用此代码设置图例...
Parts_legend <- list(
font = list(
family = "sans-serif",
size = 12,
color = "#000"),
title = list(text="<b> Delta previous month by Supplier - Absolute </b>"),
bgcolor = "#E2E2E2",
bordercolor = "#FFFFFF",
borderwidth = 2,
layout.legend = "constant",
traceorder = "grouped")
..并显示对象:
plotly_object %>%
layout(legend = Parts_legend,
title = "by supplier delta previous month",
xaxis = list(title = 'Date'),
yaxis = list(title = 'Chip Volume'))
给我留下了下面的图表,这似乎是正确的:供应商是通过名称前面的 abs(数字)输入的!
[1]: https://i.stack.imgur.com/bDTWZ.png
现在我需要添加按钮。在第一步中,我创建了两个数据框,用于指示一条线稍后是否可见 (TRUE) 或不可见 (FALSE)。
我试图以与 dat
相同的格式创建它们 - 这样我就可以为 dat
/过滤变量可以采用的值的每一行得到一个 TRUE 或 FALSE:
Parts_product_filter <- select(dat,Supplier_text,order,Product,Chip_type) %>%
mutate(Smartphones = ifelse(Product == "Smartphones",T,F) %>% sapply(.,list),
TVs = ifelse(Product == "TVs",T,F) %>% sapply(.,list),
Monitors = ifelse(Product == "Monitors",T,F) %>% sapply(.,list),
Miscellaneous = ifelse(Product == "Miscellaneous",T,F) %>% sapply(.,list))
Parts_chip_type_filter <- select(dat,Supplier_text,order,Product,Chip_type) %>%
mutate(Micro = ifelse(Chip_type == "Micro",T,F) %>% sapply(.,list),
Nano = ifelse(Chip_type == "Nano",T,F) %>% sapply(.,list),
BiMech = ifelse(Chip_type == "BiMech",T,F) %>% sapply(.,list),
Titan = ifelse(Chip_type == "Titan",T,F) %>% sapply(.,list),
Quantum = ifelse(Chip_type == "Quantum",T,F) %>% sapply(.,list),
Platinum = ifelse(Chip_type == "Platinum",T,F) %>% sapply(.,list),
PlainChip = ifelse(Chip_type == "PlainChip",T,F) %>% sapply(.,list),
Classic = ifelse(Chip_type == "Classic",T,F) %>% sapply(.,list))
将按钮添加到 plotly_object,我尝试设置它们,以便它们根据上面创建的“_filter”数据框的各个列进行过滤:
plotly_object %>%
layout(legend = Parts_legend,
title = "by supplier delta previous month",
xaxis = list(title = 'Date'),
yaxis = list(title = 'Chip Volume'),
updatemenus = list(
list(
active = 0,
type = "dropdown",
y = 1.1,
direction = "right",
# See from here:
buttons = list(
list(label = "All",
method = "restyle",
args = list("visible",T)),
list(label = "Smartphones",
method = "restyle",
args = list("visible",Parts_product_filter$Smartphones)),
list(label = "TVs",
method = "restyle",
args = list("visible",Parts_product_filter$TVs)),
list(label = "Monitors",
method = "restyle",
args = list("visible",Parts_product_filter$Monitors)),
list(label = "Miscellaneous",
method = "restyle",
args = list("visible",Parts_product_filter$Miscellaneous))
)
),
list(
active = 0,
type = "dropdown",
y = 1.03,
direction = "right",
buttons = list(
list(label = "All",
method = "restyle",
args = list("visible",T)),
list(label = "Micro",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Micro)),
list(label = "Nano",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Nano)),
list(label = "BiMech",
method = "restyle",
args = list("visible",Parts_chip_type_filter$BiMech)),
list(label = "Titan",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Titan)),
list(label = "Quantum",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Quantum)),
list(label = "Platinum",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Platinum)),
list(label = "PlainChip",
method = "restyle",
args = list("visible",Parts_chip_type_filter$PlainChip)),
list(label = "Classic",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Classic))
)
)
)
)
而这根本行不通。我一定是过滤器设置错误。我知道,因为当我过滤“Product = TVs”和“Chip_type = Nano”的组合时,没有出现线条....
https://i.stack.imgur.com/MaJ5r.png
...虽然有数据:
> dat %>% filter(Product == "TVs") %>% filter(Chip_type == "Nano")
# A tibble: 8 x 7
Date Supplier Supplier_text order Chip_type Product n
<chr> <chr> <chr> <int> <chr> <chr> <chr>
1 2019-11 Overall TVs 14373 | 6.0% - Overall TVs 4 Nano TVs 4643
2 2019-12 Overall TVs 14373 | 6.0% - Overall TVs 4 Nano TVs 6904
3 2019-11 J 2603 | 5.8% - J 13 Nano TVs 3
4 2019-12 J 2603 | 5.8% - J 13 Nano TVs 3
5 2019-11 M -1711 | -19.4% - M 16 Nano TVs 2
6 2019-12 M -1711 | -19.4% - M 16 Nano TVs 1
7 2019-11 O 1315 | 23.6% - O 19 Nano TVs 2
8 2019-12 O 1315 | 23.6% - O 19 Nano TVs 1
我真的很期待你的建议如何正确设置按钮的可见性切换!
我知道有两个相似的post,但是关注的是多张图。很可能是我技术不够,但我无法通过提供的解决方案解决我的问题,非常感谢您的考虑和帮助!
在 Python(不是 R)中完成的类似内容,但使用一个过滤器:
后续将是:是否可以select多个类别,i。 e. “Nano”和“Classic”,可能同时来自另一个过滤器的“智能手机”和“电视”?
这是 Python 的 post,但不幸的是没有答案:
Selecting multiple buttons at once in a plotly graph
在此先感谢您!
要导入的完整数据集:
<!-- begin snippet: js hide: true -->
dat <- structure(list(Date = c("2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-11", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-12", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-12", "2019-12", "2019-11",
"2019-12", "2019-12", "2019-11", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-12", "2019-12", "2019-11", "2019-11", "2019-11",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-11", "2019-11",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-12", "2019-12"), Supplier = c("Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"A", "A", "A", "A", "A", "A", "A", "A", "Overall TVs", "Overall TVs",
"Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs",
"Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs",
"Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs", "B",
"B", "B", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C",
"C", "C", "C", "C", "D", "D", "D", "D", "D", "D", "D", "D", "D",
"D", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "F",
"F", "F", "F", "G", "G", "G", "H", "H", "H", "H", "H", "I", "I",
"I", "I", "I", "J", "J", "J", "J", "K", "K", "K", "K", "K", "L",
"L", "L", "L", "L", "L", "M", "M", "M", "M", "M", "M", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "N", "N", "N",
"N", "N", "N", "N", "O", "O", "O", "O", "O", "O", "P", "P", "P",
"P", "P", "P", "P", "P", "C", "C", "C", "C", "C", "C", "Q", "Q",
"Q", "R", "R", "R", "S"), Supplier_text = c("94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-17385 | -88.0% - A",
"-17385 | -88.0% - A", "-17385 | -88.0% - A", "-17385 | -88.0% - A",
"-17385 | -88.0% - A", "-17385 | -88.0% - A", "-17385 | -88.0% - A",
"-17385 | -88.0% - A", "14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"-8387 | -80.6% - B", "-8387 | -80.6% - B", "-8387 | -80.6% - B",
"-8387 | -80.6% - B", "-8387 | -80.6% - B", "-8387 | -80.6% - B",
"-8387 | -80.6% - B", "-8387 | -80.6% - B", "-8387 | -80.6% - B",
"5701 | 79.2% - C", "5701 | 79.2% - C", "5701 | 79.2% - C",
"5701 | 79.2% - C", "5701 | 79.2% - C", "5701 | 79.2% - C",
"5701 | 79.2% - C", "5701 | 79.2% - C", "5701 | 79.2% - C",
"5155 | 49.2% - D", "5155 | 49.2% - D", "5155 | 49.2% - D",
"5155 | 49.2% - D", "5155 | 49.2% - D", "5155 | 49.2% - D",
"5155 | 49.2% - D", "5155 | 49.2% - D", "5155 | 49.2% - D",
"5155 | 49.2% - D", "4977 | 95.4% - E", "4977 | 95.4% - E",
"4977 | 95.4% - E", "4977 | 95.4% - E", "4977 | 95.4% - E",
"4977 | 95.4% - E", "4977 | 95.4% - E", "4977 | 95.4% - E",
"4977 | 95.4% - E", "4977 | 95.4% - E", "4977 | 95.4% - E",
"3676 |18380.0% - F", "3676 |18380.0% - F", "3676 |18380.0% - F",
"3676 |18380.0% - F", "-3132 | -99.4% - G", "-3132 | -99.4% - G",
"-3132 | -99.4% - G", "3065 | 33.6% - H", "3065 | 33.6% - H",
"3065 | 33.6% - H", "3065 | 33.6% - H", "3065 | 33.6% - H",
"-2854 | -56.1% - I", "-2854 | -56.1% - I", "-2854 | -56.1% - I",
"-2854 | -56.1% - I", "-2854 | -56.1% - I", "2603 | 5.8% - J",
"2603 | 5.8% - J", "2603 | 5.8% - J", "2603 | 5.8% - J",
"2564 | 39.4% - K", "2564 | 39.4% - K", "2564 | 39.4% - K",
"2564 | 39.4% - K", "2564 | 39.4% - K", "1843 | 334.5% - L",
"1843 | 334.5% - L", "1843 | 334.5% - L", "1843 | 334.5% - L",
"1843 | 334.5% - L", "1843 | 334.5% - L", "-1711 | -19.4% - M",
"-1711 | -19.4% - M", "-1711 | -19.4% - M", "-1711 | -19.4% - M",
"-1711 | -19.4% - M", "-1711 | -19.4% - M", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1439 | -95.6% - N", "-1439 | -95.6% - N", "-1439 | -95.6% - N",
"-1439 | -95.6% - N", "-1439 | -95.6% - N", "-1439 | -95.6% - N",
"-1439 | -95.6% - N", "1315 | 23.6% - O", "1315 | 23.6% - O",
"1315 | 23.6% - O", "1315 | 23.6% - O", "1315 | 23.6% - O",
"1315 | 23.6% - O", "193 | 232.5% - P", "193 | 232.5% - P",
"193 | 232.5% - P", "193 | 232.5% - P", "193 | 232.5% - P",
"193 | 232.5% - P", "193 | 232.5% - P", "193 | 232.5% - P",
"-152 | -38.1% - C", "-152 | -38.1% - C", "-152 | -38.1% - C",
"-152 | -38.1% - C", "-152 | -38.1% - C", "-152 | -38.1% - C",
"-98 | -79.7% - Q", "-98 | -79.7% - Q", "-98 | -79.7% - Q",
"92 | 3066.7% - R", "92 | 3066.7% - R", "92 | 3066.7% - R", "-70 | -90.9% - S"
), order = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L,
5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L,
7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L,
8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 11L, 11L, 11L,
11L, 11L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 14L, 14L,
14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L,
16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L,
17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L,
19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 21L,
21L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 23L, 23L, 23L, 24L),
Chip_type = c("Micro", "Nano", "BiMech", "Titan", "Quantum",
"Platinum", "PlainChip", "Classic", "Micro", "Nano", "BiMech",
"Titan", "Quantum", "Platinum", "PlainChip", "Classic", "Micro",
"Nano", "BiMech", "Titan", "Quantum", "Platinum", "PlainChip",
"Classic", "Micro", "Nano", "BiMech", "Titan", "Quantum",
"Platinum", "PlainChip", "Classic", "Titan", "Platinum",
"Quantum", "Nano", "Titan", "Platinum", "Nano", "PlainChip",
"Micro", "Nano", "BiMech", "Titan", "Quantum", "Platinum",
"PlainChip", "Classic", "Micro", "Nano", "BiMech", "Titan",
"Quantum", "Platinum", "PlainChip", "Classic", "Titan", "Platinum",
"Quantum", "Nano", "Titan", "Nano", "Quantum", "Platinum",
"PlainChip", "PlainChip", "Platinum", "Nano", "Quantum",
"Classic", "PlainChip", "Platinum", "Nano", "Quantum", "PlainChip",
"Platinum", "Quantum", "Nano", "Classic", "PlainChip", "Nano",
"Platinum", "Quantum", "Classic", "PlainChip", "Quantum",
"Platinum", "Classic", "Nano", "PlainChip", "Quantum", "Platinum",
"Nano", "Classic", "BiMech", "Titan", "Nano", "Titan", "Quantum",
"Titan", "Titan", "Platinum", "PlainChip", "Nano", "Classic",
"PlainChip", "Nano", "PlainChip", "PlainChip", "Quantum",
"Nano", "Classic", "Titan", "Nano", "Titan", "Nano", "Platinum",
"PlainChip", "Quantum", "Platinum", "PlainChip", "Titan",
"PlainChip", "Platinum", "Titan", "PlainChip", "Platinum",
"Titan", "Nano", "Titan", "Platinum", "Nano", "PlainChip",
"Nano", "BiMech", "Titan", "Quantum", "Platinum", "PlainChip",
"Classic", "Micro", "Nano", "BiMech", "Titan", "Quantum",
"Platinum", "PlainChip", "Classic", "Titan", "Quantum", "Titan",
"Nano", "Quantum", "Platinum", "PlainChip", "Titan", "Quantum",
"Nano", "Micro", "Titan", "Nano", "Platinum", "Quantum",
"Nano", "Classic", "Quantum", "Platinum", "Nano", "Classic",
"Classic", "Quantum", "Nano", "Classic", "Quantum", "Nano",
"Quantum", "Quantum", "Nano", "Quantum", "Nano", "Quantum",
"Titan"), Product = c("Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs",
"TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs",
"TVs", "Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "TVs", "TVs", "TVs",
"TVs", "Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs",
"TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous"
), n = c("106", "16920", "61216", "363698", "50797", "52715",
"174342", "9319", "92", "16928", "40920", "270963", "48605",
"34068", "114333", "4024", "3", "1536", "6793", "45146",
"7922", "5359", "27390", "1131", "12", "1311", "5431", "48107",
"6230", "5133", "21161", "505", "3619", "13", "2", "1", "19720",
"13", "10", "4", "96", "4643", "14534", "166664", "17178",
"17489", "30048", "5010", "96", "6904", "10463", "158060",
"15864", "20149", "24173", "2390", "12102", "7", "2", "1",
"10390", "5", "4", "2", "1", "11036", "329", "224", "2",
"2", "6936", "176", "85", "1", "15335", "55", "53", "48",
"14", "10292", "86", "47", "32", "11", "6559", "667", "631",
"419", "416", "4416", "336", "285", "105", "74", "2", "18",
"2", "18", "2", "86", "3151", "1", "14682", "77", "10", "9098",
"26", "2833", "5083", "2", "1", "1", "41051", "3", "45233",
"3", "10763", "44", "2", "6508", "2", "370", "265", "6",
"461", "86", "4", "5996", "2", "8826", "2", "1", "1", "503",
"5", "79", "3348", "742", "199", "989", "1", "473", "11",
"152", "3681", "363", "54", "804", "1702", "1", "1500", "2",
"1", "1", "1", "4868", "5", "2", "1", "5573", "1", "312",
"113", "3", "3", "42", "30", "6", "5", "371", "53", "19",
"312", "64", "23", "97", "121", "2", "3", "1", "3", "77")), row.names = c(NA,
-182L), class = c("tbl_df", "tbl", "data.frame"))
#[1]: https://i.stack.imgur.com/bDTWZ.png
#[2]: https://i.stack.imgur.com/MaJ5r.png
您创建了一个包含 182 个 T 或 F 的列表,但您真正需要的是一个包含 24 个 T 或 F 的列表,因为有 24 行、24 组、24 条迹线plotly 是要显示还是不显示。
首先,您很好地按数据中的字段对绘图进行了分组。我有第一个情节的另一种变体 - 一次调用 plot_ly
并且仍然创建所有 24 条轨迹,就像你的循环一样。
首先我做了 Supplier_text
和排序因子,这样我就可以控制图例的顺序。
# this will keep the legend order in order
d2 <- dat %>%
mutate(Supplier_text = ordered(Supplier_text,
levels = rev(unique(dat$Supplier_text))))
然后我创建了 24 条轨迹。
(plt <- plot_ly(data = d2,
x = ~Date,
y = ~n,
color = ~Supplier_text,
type = "scatter",
mode = "lines"))
然后我更改了您为产品创建的过滤器。你有 24 条轨迹,现在你有 24 个 T 或 F 用于此过滤器。
# changed this so it is one for each trace, not one for each row
Parts_product_filter <- d2 %>% select(Supplier_text, Product) %>%
mutate(Smartphones = ifelse(Product == "Smartphones",T,F) %>% sapply(.,list),
TVs = ifelse(Product == "TVs",T, F) %>% sapply(.,list),
Monitors = ifelse(Product == "Monitors",T,F) %>% sapply(.,list),
Miscellaneous = ifelse(Product == "Miscellaneous",T,F) %>% sapply(.,list)) %>%
unique()
你的代码的其他部分保持不变,除了 plotly_object
的对象名称,现在 plt
在连接绘图的任何调用中(两个布局和 Chip_type
过滤器)。
更新替换
这仅包括“两者”按钮。
我在评论中回答你的问题,发现有些痕迹不对劲。所以当我解决这个问题时,我还添加了悬停,这样你就可以想象为什么会出现垂直线。请记住,n
是一个因素。 Plotly
不知道您要将哪个 n
值与右侧的哪个值连接,而不是通过 color.
当您将 n
设为数字字段时,plotly
会将这些值相加(除非您提供 plotly
其他划分内容的方式)。可悲的是,计算机无法读懂思想......但是......
我添加了一个 hovertemplate。如果您在图例中看到情节中没有的内容,那是 plotly
不知道该怎么做。如果将鼠标悬停在图上,您甚至可能会得到一个值,但没有线。我在最后有一些例子。
d2 <- dat %>%
mutate(Supplier_text = ordered(Supplier_text,
levels = rev(unique(dat$Supplier_text))),
Product = ordered(Product,
levels = sort(unique(dat$Product))),
Chip_type = ordered(Chip_type,
levels = sort(unique(dat$Chip_type))),
n = as.numeric(dat$n) %>% sort(decreasing = T) %>%
as.character() %>% ordered(., levels = unique(.))) %>%
arrange(n)
所有痕迹:
#------------- base plot ----------------
(plt <- d2 %>%
plot_ly(x = ~Date,
y = ~n,
color = ~Supplier_text,
type = 'scatter',
mode = 'lines',
text = ~Product,
hovertext = ~Chip_type,
visible = T
))
我意识到当我计算痕迹时,当绘图呈现时,我没有得到 45 条痕迹,我得到了更多!只有基本图有 24 条迹线。底座和组合键都有127条轨迹。
这就是我想出并验证更正的方式。
#------------- trace count ----------------
# I used length(plt$x$attrs) to confirm the number of traces
# -- that was a mistake!
# collect data, since it's not in the plotly object (errr)
pj = plotly_json(plt)
# read the JSON back
pjj = jsonlite::fromJSON(pj$x$data)
# number of traces:
nrow(pjj$data)
# [1] 24 # one trace for each color
组合痕迹:
#------------- add combination traces ----------------
# each of the possible button groups when both filters are opted
cmb = expand.grid(Product = levels(d2$Product),
Chip_type = levels(d2$Chip_type))
# create combo traces
invisible(
lapply(1:nrow(cmb), # filter for both
function(x){
d3 = d2 %>% filter(Product == cmb[x, 1] %>% toString(),
Chip_type == cmb[x, 2] %>% toString()) %>%
droplevels
if(nrow(d3) < 1) {
print(cmb[x, ]) # let me know what was skipped
return() # if no rows, don't make the trace
} # end if
plt <<- plt %>%
add_trace(inherit = F,
data = d2 %>%
filter(Product == cmb[x, 1] %>% toString(),
Chip_type == cmb[x, 2] %>% toString()),
x = ~Date, y = ~n,
color = ~Supplier_text,
type = 'scatter',
mode = 'lines',
text = ~Product,
hovertext = ~Chip_type,
hovertemplate = paste0("Products: %{text}",
"\nChips: %{hovertext}"),
visible = F #,
#inherit = F
)
})
)
cmb # validate
现在查看痕迹数:
#------------- combination traces updated trace count ----------------
# collect count
pj = plotly_json(plt)
# read the JSON back
pjj = jsonlite::fromJSON(pj$x$data)
# number of traces:
nrow(pjj$data)
# [1] 127 # whoa!
根据痕迹创建数据以确保 T/F 是正确的
#------------- trace data frame ----------------
# create data frame of the JSON content so that traces can be match with combos
plt.df = data.frame(nm = pjj$data$name, # this is Supplier_text
# valCount is the number of observations in the trace
valCount = unlist(map(pjj$data$x, ~length(.x))),
# whether it's visible (is it all or not?)
vis = pjj$data$visible)
# inspect what you expect
tail(plt.df)
按钮组合部分
#------------- set up for button for combos ----------------
tracs = d2 %>%
group_by(Product, Chip_type, Supplier_text) %>%
summarise(ct = n(), .groups = "drop") %>%
mutate(traces = 25:127)
# is the order the same in the plot?
tail(tracs, 10)
tail(plt.df, 10) # definitely not!
# check?
tracs %>% arrange(Chip_type) %>% tail(10)
# that's the right order
# update tracs' order
tracs <- tracs %>% arrange(Chip_type) %>%
mutate(traces = 25:nrow(plt.df)) # fix trace assignment
# double-check!
plt.df[25:35,]
tracs[1:11,]
# they aren't the same, but plotting groups are
# adjust cmb to be ordered before id trace to group combos
cmb <- cmb %>% arrange(Chip_type)
现在数据已对齐 (order-wise),我们需要准确找到哪些轨迹与哪些组相关。组中的每种颜色都会有一条轨迹(即,如果 Misc Titan 在 3 种不同颜色中有 5 进/5 出,则 Misc Titan 将有三个轨迹。
#--------------- collect group to trace number ----------------
# between cmb, d2, and the traces, the three vars - product, chip, and
# supplier text are ordered factors so the order will be the same
cmbo = invisible(
lapply(1:nrow(cmb),
function(x){
rs = tracs %>% filter(Product == cmb[x, 1] %>% toString(),
Chip_type == cmb[x, 2] %>% toString()) %>%
select(traces) %>% unlist() %>% unique(use.names = F)
list(traces = rs)
}) %>% setNames(paste0(cmb[, 1], " ", cmb[, 2])) # add the names
)# 32 start and stop points for the 103 traces
# check
cmbo[1:6]
现在按钮布局代码可以写成:
#---------------------- the button ----------------------
# now for the buttons...finally
# create the empty
raw_v <- rep(F, nrow(plt.df))
cButton <-
lapply(1:length(cmbo),
function(x){
traces <- cmbo[[x]][[1]] %>% unlist()
raw_v[traces] <- T
as.list(unlist(raw_v))
}) %>% setNames(names(cmbo))
# validate
length(cButton[[1]])
# [1] 127
length(cButton)
# [1] 32
# looks good
cmbBtn2 = lapply(1:length(cButton),
function(x){
label = names(cButton)[x] %>% gsub("\.", " ", x = .)
method = "restyle"
args = list("visible", cButton[[x]])
list(label = label, method = method, args = args)
})
按钮的all
部分
#------------- set up button for "all" ----------------
all = list(list(label = "All",
method = "restyle",
args = list("visible",
as.list(unlist(
c(rep(T, 24),
rep(F, nrow(plt.df) - 24)
)))) # end args
)) # end list list
现在把它们放在一起:
#---------------------- the layout ----------------------
Parts_legend <- list(
font = list(
family = "sans-serif",
size = 12,
color = "#000"),
title = list(text="<b> Delta previous month by Supplier - Absolute </b>"),
bgcolor = "#E2E2E2",
bordercolor = "#FFFFFF",
borderwidth = 2,
layout.legend = "constant",
traceorder = "grouped")
plt %>%
layout(legend = Parts_legend,
title = "by supplier delta previous month",
xaxis = list(title = 'Date'),
yaxis = list(title = 'Chip Volume'),
margin = list(l = 120, t = 100),
updatemenus = list(
list(
active = 0,
type = "dropdown",
y = 1.2,
direction = "down",
buttons = append(all, cmbBtn2)))
) # end layout
一些检查:
# check some of these for accuracy
d2 %>% filter(Product == "TVs", Chip_type == "PlainChip") # correct
d2 %>% filter(Product == "Miscellaneous", Chip_type == "BiMech") # correct
d2 %>% filter(Product == "Monitors", Chip_type == "Classic") # NOT right!
# there are 2 in and 2 out, but 1 in and 1 out match,
# the other's are different colors, so the line's not drawn
d2 %>% filter(Product == "TVs", Chip_type == "Micro") # not correct;
# that's because there is more in than out
最后一件事,我终于停下来了!垂直线——我放大了 'All'。这是同一图、相同缩放、相同 quasi-horizontal 线、相同 垂直 线的多个视图:
比方说,plotly
的所有规则都是 x、y 和颜色。它不关心其他数据,你没有那样绑定它(好吧,我没有)。
我正在尝试使用 R plot_ly 创建折线图,可以使用沿“产品”和“Chip_type”过滤的过滤器按钮打开和关闭折线图。 这个想法是供应商(“供应商”/“Supplier_text”)每月(“日期”)为公司的不同产品部门(“产品”)供应不同种类的芯片(“Chip_type”) .为了了解顶级供应商的概况,我想为每个供应商画一条线,图例中显示“Supplier_text”,图例条目按显示在“[”前面的 abs(number) 降序排序=67=]”。在这方面,数据 tibble 被正确排序。 “总体”条目是指该产品的所有供应商的总和。
可在 post 的末尾找到完整的数据集。
sample from dat :
Date(chr) Supplier Supplier_text order(int) Chip_type Product n(chr)
1 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Micro Smartphones 106
2 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Nano Smartphones 16920
3 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 BiMech Smartphones 61216
4 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Titan Smartphones 363698
5 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Quantum Smartphones 50797
6 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Platinum Smartphones 52715
7 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 PlainChip Smartphones 174342
8 2019-11 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Classic Smartphones 9319
9 2019-12 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Micro Smartphones 92
10 2019-12 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 Nano Smartphones 16928
11 2019-12 Overall Smartphones 94757 | 17.9% - Overall Smartphones 1 BiMech Smartphones 40920
17 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Micro Monitors 3
18 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Nano Monitors 1536
19 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 BiMech Monitors 6793
20 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Titan Monitors 45146
21 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Quantum Monitors 7922
22 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Platinum Monitors 5359
23 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 PlainChip Monitors 27390
24 2019-11 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Classic Monitors 1131
25 2019-12 Overall Monitors -33239 | -37.8% - Overall Monitors 2 Micro Monitors 12
33 2019-11 A -17385 | -88.0% - A 3 Titan Smartphones 3619
34 2019-11 A -17385 | -88.0% - A 3 Platinum Smartphones 13
35 2019-11 A -17385 | -88.0% - A 3 Quantum Smartphones 2
为了保持顺序(稍后能够切换正确的行!)我正在循环添加跟踪到一个空的 plot_ly 对象,如下所示:
library(stringr)
library(dplyr)
library(plotly)
# "Rebuilding" the data frame as the loop runs to see if what the loop does to the traces ends up being the same (order) as the original data frame. For that, I create an empty object first:
dat_plotly_object_copy = c()
plotly_object <- plot_ly()
id = 1
# I loop along "order", which marks all data of a single supplier:
for(id in 1:max(dat$order)){
dat_one_supplier <- filter(dat, order == id)
plotly_object <- plotly_object %>% add_trace(., data = dat_one_supplier,
# I filter the data set by supplier, to be able to create a line along the dates (~x) per supplier (~Supplier_text) and Chip_type (~n):
x = ~Date,
y = ~n,
color = ~Supplier_text,
type = "scatter",
mode = "lines")
dat_plotly_object_copy <- dat_plotly_object_copy %>%
rbind(.,dat_one_supplier)
}
identical(dat, dat_plotly_object_copy)
# The created data frame seems to be identical to what the loop does - so the order should match (?)
使用此代码设置图例...
Parts_legend <- list(
font = list(
family = "sans-serif",
size = 12,
color = "#000"),
title = list(text="<b> Delta previous month by Supplier - Absolute </b>"),
bgcolor = "#E2E2E2",
bordercolor = "#FFFFFF",
borderwidth = 2,
layout.legend = "constant",
traceorder = "grouped")
..并显示对象:
plotly_object %>%
layout(legend = Parts_legend,
title = "by supplier delta previous month",
xaxis = list(title = 'Date'),
yaxis = list(title = 'Chip Volume'))
给我留下了下面的图表,这似乎是正确的:供应商是通过名称前面的 abs(数字)输入的! [1]: https://i.stack.imgur.com/bDTWZ.png
现在我需要添加按钮。在第一步中,我创建了两个数据框,用于指示一条线稍后是否可见 (TRUE) 或不可见 (FALSE)。
我试图以与 dat
相同的格式创建它们 - 这样我就可以为 dat
/过滤变量可以采用的值的每一行得到一个 TRUE 或 FALSE:
Parts_product_filter <- select(dat,Supplier_text,order,Product,Chip_type) %>%
mutate(Smartphones = ifelse(Product == "Smartphones",T,F) %>% sapply(.,list),
TVs = ifelse(Product == "TVs",T,F) %>% sapply(.,list),
Monitors = ifelse(Product == "Monitors",T,F) %>% sapply(.,list),
Miscellaneous = ifelse(Product == "Miscellaneous",T,F) %>% sapply(.,list))
Parts_chip_type_filter <- select(dat,Supplier_text,order,Product,Chip_type) %>%
mutate(Micro = ifelse(Chip_type == "Micro",T,F) %>% sapply(.,list),
Nano = ifelse(Chip_type == "Nano",T,F) %>% sapply(.,list),
BiMech = ifelse(Chip_type == "BiMech",T,F) %>% sapply(.,list),
Titan = ifelse(Chip_type == "Titan",T,F) %>% sapply(.,list),
Quantum = ifelse(Chip_type == "Quantum",T,F) %>% sapply(.,list),
Platinum = ifelse(Chip_type == "Platinum",T,F) %>% sapply(.,list),
PlainChip = ifelse(Chip_type == "PlainChip",T,F) %>% sapply(.,list),
Classic = ifelse(Chip_type == "Classic",T,F) %>% sapply(.,list))
将按钮添加到 plotly_object,我尝试设置它们,以便它们根据上面创建的“_filter”数据框的各个列进行过滤:
plotly_object %>%
layout(legend = Parts_legend,
title = "by supplier delta previous month",
xaxis = list(title = 'Date'),
yaxis = list(title = 'Chip Volume'),
updatemenus = list(
list(
active = 0,
type = "dropdown",
y = 1.1,
direction = "right",
# See from here:
buttons = list(
list(label = "All",
method = "restyle",
args = list("visible",T)),
list(label = "Smartphones",
method = "restyle",
args = list("visible",Parts_product_filter$Smartphones)),
list(label = "TVs",
method = "restyle",
args = list("visible",Parts_product_filter$TVs)),
list(label = "Monitors",
method = "restyle",
args = list("visible",Parts_product_filter$Monitors)),
list(label = "Miscellaneous",
method = "restyle",
args = list("visible",Parts_product_filter$Miscellaneous))
)
),
list(
active = 0,
type = "dropdown",
y = 1.03,
direction = "right",
buttons = list(
list(label = "All",
method = "restyle",
args = list("visible",T)),
list(label = "Micro",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Micro)),
list(label = "Nano",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Nano)),
list(label = "BiMech",
method = "restyle",
args = list("visible",Parts_chip_type_filter$BiMech)),
list(label = "Titan",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Titan)),
list(label = "Quantum",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Quantum)),
list(label = "Platinum",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Platinum)),
list(label = "PlainChip",
method = "restyle",
args = list("visible",Parts_chip_type_filter$PlainChip)),
list(label = "Classic",
method = "restyle",
args = list("visible",Parts_chip_type_filter$Classic))
)
)
)
)
而这根本行不通。我一定是过滤器设置错误。我知道,因为当我过滤“Product = TVs”和“Chip_type = Nano”的组合时,没有出现线条....
https://i.stack.imgur.com/MaJ5r.png
...虽然有数据:
> dat %>% filter(Product == "TVs") %>% filter(Chip_type == "Nano")
# A tibble: 8 x 7
Date Supplier Supplier_text order Chip_type Product n
<chr> <chr> <chr> <int> <chr> <chr> <chr>
1 2019-11 Overall TVs 14373 | 6.0% - Overall TVs 4 Nano TVs 4643
2 2019-12 Overall TVs 14373 | 6.0% - Overall TVs 4 Nano TVs 6904
3 2019-11 J 2603 | 5.8% - J 13 Nano TVs 3
4 2019-12 J 2603 | 5.8% - J 13 Nano TVs 3
5 2019-11 M -1711 | -19.4% - M 16 Nano TVs 2
6 2019-12 M -1711 | -19.4% - M 16 Nano TVs 1
7 2019-11 O 1315 | 23.6% - O 19 Nano TVs 2
8 2019-12 O 1315 | 23.6% - O 19 Nano TVs 1
我真的很期待你的建议如何正确设置按钮的可见性切换!
我知道有两个相似的post,但是关注的是多张图。很可能是我技术不够,但我无法通过提供的解决方案解决我的问题,非常感谢您的考虑和帮助!
在 Python(不是 R)中完成的类似内容,但使用一个过滤器:
后续将是:是否可以select多个类别,i。 e. “Nano”和“Classic”,可能同时来自另一个过滤器的“智能手机”和“电视”? 这是 Python 的 post,但不幸的是没有答案: Selecting multiple buttons at once in a plotly graph
在此先感谢您!
要导入的完整数据集:
<!-- begin snippet: js hide: true -->
dat <- structure(list(Date = c("2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-11", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-11", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-12", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-12", "2019-12", "2019-11",
"2019-12", "2019-12", "2019-11", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-11", "2019-11",
"2019-11", "2019-12", "2019-12", "2019-11", "2019-11", "2019-11",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-11", "2019-11",
"2019-11", "2019-11", "2019-11", "2019-11", "2019-12", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-12", "2019-12", "2019-12", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-11", "2019-11", "2019-11", "2019-11", "2019-12",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-11", "2019-11",
"2019-12", "2019-12", "2019-12", "2019-11", "2019-12", "2019-12",
"2019-11", "2019-11", "2019-12", "2019-12"), Supplier = c("Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Smartphones", "Overall Smartphones", "Overall Smartphones",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"Overall Monitors", "Overall Monitors", "Overall Monitors", "Overall Monitors",
"A", "A", "A", "A", "A", "A", "A", "A", "Overall TVs", "Overall TVs",
"Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs",
"Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs",
"Overall TVs", "Overall TVs", "Overall TVs", "Overall TVs", "B",
"B", "B", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C",
"C", "C", "C", "C", "D", "D", "D", "D", "D", "D", "D", "D", "D",
"D", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "F",
"F", "F", "F", "G", "G", "G", "H", "H", "H", "H", "H", "I", "I",
"I", "I", "I", "J", "J", "J", "J", "K", "K", "K", "K", "K", "L",
"L", "L", "L", "L", "L", "M", "M", "M", "M", "M", "M", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "Overall Miscellaneous",
"Overall Miscellaneous", "Overall Miscellaneous", "N", "N", "N",
"N", "N", "N", "N", "O", "O", "O", "O", "O", "O", "P", "P", "P",
"P", "P", "P", "P", "P", "C", "C", "C", "C", "C", "C", "Q", "Q",
"Q", "R", "R", "R", "S"), Supplier_text = c("94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "94757 | 17.9% - Overall Smartphones",
"94757 | 17.9% - Overall Smartphones", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-33239 | -37.8% - Overall Monitors",
"-33239 | -37.8% - Overall Monitors", "-17385 | -88.0% - A",
"-17385 | -88.0% - A", "-17385 | -88.0% - A", "-17385 | -88.0% - A",
"-17385 | -88.0% - A", "-17385 | -88.0% - A", "-17385 | -88.0% - A",
"-17385 | -88.0% - A", "14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"14373 | 6.0% - Overall TVs", "14373 | 6.0% - Overall TVs",
"-8387 | -80.6% - B", "-8387 | -80.6% - B", "-8387 | -80.6% - B",
"-8387 | -80.6% - B", "-8387 | -80.6% - B", "-8387 | -80.6% - B",
"-8387 | -80.6% - B", "-8387 | -80.6% - B", "-8387 | -80.6% - B",
"5701 | 79.2% - C", "5701 | 79.2% - C", "5701 | 79.2% - C",
"5701 | 79.2% - C", "5701 | 79.2% - C", "5701 | 79.2% - C",
"5701 | 79.2% - C", "5701 | 79.2% - C", "5701 | 79.2% - C",
"5155 | 49.2% - D", "5155 | 49.2% - D", "5155 | 49.2% - D",
"5155 | 49.2% - D", "5155 | 49.2% - D", "5155 | 49.2% - D",
"5155 | 49.2% - D", "5155 | 49.2% - D", "5155 | 49.2% - D",
"5155 | 49.2% - D", "4977 | 95.4% - E", "4977 | 95.4% - E",
"4977 | 95.4% - E", "4977 | 95.4% - E", "4977 | 95.4% - E",
"4977 | 95.4% - E", "4977 | 95.4% - E", "4977 | 95.4% - E",
"4977 | 95.4% - E", "4977 | 95.4% - E", "4977 | 95.4% - E",
"3676 |18380.0% - F", "3676 |18380.0% - F", "3676 |18380.0% - F",
"3676 |18380.0% - F", "-3132 | -99.4% - G", "-3132 | -99.4% - G",
"-3132 | -99.4% - G", "3065 | 33.6% - H", "3065 | 33.6% - H",
"3065 | 33.6% - H", "3065 | 33.6% - H", "3065 | 33.6% - H",
"-2854 | -56.1% - I", "-2854 | -56.1% - I", "-2854 | -56.1% - I",
"-2854 | -56.1% - I", "-2854 | -56.1% - I", "2603 | 5.8% - J",
"2603 | 5.8% - J", "2603 | 5.8% - J", "2603 | 5.8% - J",
"2564 | 39.4% - K", "2564 | 39.4% - K", "2564 | 39.4% - K",
"2564 | 39.4% - K", "2564 | 39.4% - K", "1843 | 334.5% - L",
"1843 | 334.5% - L", "1843 | 334.5% - L", "1843 | 334.5% - L",
"1843 | 334.5% - L", "1843 | 334.5% - L", "-1711 | -19.4% - M",
"-1711 | -19.4% - M", "-1711 | -19.4% - M", "-1711 | -19.4% - M",
"-1711 | -19.4% - M", "-1711 | -19.4% - M", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1662 | -30.0% - Overall Miscellaneous", "-1662 | -30.0% - Overall Miscellaneous",
"-1439 | -95.6% - N", "-1439 | -95.6% - N", "-1439 | -95.6% - N",
"-1439 | -95.6% - N", "-1439 | -95.6% - N", "-1439 | -95.6% - N",
"-1439 | -95.6% - N", "1315 | 23.6% - O", "1315 | 23.6% - O",
"1315 | 23.6% - O", "1315 | 23.6% - O", "1315 | 23.6% - O",
"1315 | 23.6% - O", "193 | 232.5% - P", "193 | 232.5% - P",
"193 | 232.5% - P", "193 | 232.5% - P", "193 | 232.5% - P",
"193 | 232.5% - P", "193 | 232.5% - P", "193 | 232.5% - P",
"-152 | -38.1% - C", "-152 | -38.1% - C", "-152 | -38.1% - C",
"-152 | -38.1% - C", "-152 | -38.1% - C", "-152 | -38.1% - C",
"-98 | -79.7% - Q", "-98 | -79.7% - Q", "-98 | -79.7% - Q",
"92 | 3066.7% - R", "92 | 3066.7% - R", "92 | 3066.7% - R", "-70 | -90.9% - S"
), order = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L,
5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L,
7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L,
8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 11L, 11L, 11L,
11L, 11L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 14L, 14L,
14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L,
16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L,
17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L,
19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 21L,
21L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 23L, 23L, 23L, 24L),
Chip_type = c("Micro", "Nano", "BiMech", "Titan", "Quantum",
"Platinum", "PlainChip", "Classic", "Micro", "Nano", "BiMech",
"Titan", "Quantum", "Platinum", "PlainChip", "Classic", "Micro",
"Nano", "BiMech", "Titan", "Quantum", "Platinum", "PlainChip",
"Classic", "Micro", "Nano", "BiMech", "Titan", "Quantum",
"Platinum", "PlainChip", "Classic", "Titan", "Platinum",
"Quantum", "Nano", "Titan", "Platinum", "Nano", "PlainChip",
"Micro", "Nano", "BiMech", "Titan", "Quantum", "Platinum",
"PlainChip", "Classic", "Micro", "Nano", "BiMech", "Titan",
"Quantum", "Platinum", "PlainChip", "Classic", "Titan", "Platinum",
"Quantum", "Nano", "Titan", "Nano", "Quantum", "Platinum",
"PlainChip", "PlainChip", "Platinum", "Nano", "Quantum",
"Classic", "PlainChip", "Platinum", "Nano", "Quantum", "PlainChip",
"Platinum", "Quantum", "Nano", "Classic", "PlainChip", "Nano",
"Platinum", "Quantum", "Classic", "PlainChip", "Quantum",
"Platinum", "Classic", "Nano", "PlainChip", "Quantum", "Platinum",
"Nano", "Classic", "BiMech", "Titan", "Nano", "Titan", "Quantum",
"Titan", "Titan", "Platinum", "PlainChip", "Nano", "Classic",
"PlainChip", "Nano", "PlainChip", "PlainChip", "Quantum",
"Nano", "Classic", "Titan", "Nano", "Titan", "Nano", "Platinum",
"PlainChip", "Quantum", "Platinum", "PlainChip", "Titan",
"PlainChip", "Platinum", "Titan", "PlainChip", "Platinum",
"Titan", "Nano", "Titan", "Platinum", "Nano", "PlainChip",
"Nano", "BiMech", "Titan", "Quantum", "Platinum", "PlainChip",
"Classic", "Micro", "Nano", "BiMech", "Titan", "Quantum",
"Platinum", "PlainChip", "Classic", "Titan", "Quantum", "Titan",
"Nano", "Quantum", "Platinum", "PlainChip", "Titan", "Quantum",
"Nano", "Micro", "Titan", "Nano", "Platinum", "Quantum",
"Nano", "Classic", "Quantum", "Platinum", "Nano", "Classic",
"Classic", "Quantum", "Nano", "Classic", "Quantum", "Nano",
"Quantum", "Quantum", "Nano", "Quantum", "Nano", "Quantum",
"Titan"), Product = c("Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs",
"TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs",
"TVs", "Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "TVs", "TVs", "TVs",
"TVs", "Smartphones", "Smartphones", "Smartphones", "Smartphones",
"Smartphones", "TVs", "TVs", "TVs", "TVs", "TVs", "TVs",
"TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Monitors", "Monitors",
"Monitors", "Monitors", "Monitors", "Monitors", "Monitors",
"TVs", "TVs", "TVs", "TVs", "TVs", "TVs", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous",
"Miscellaneous", "Miscellaneous", "Miscellaneous", "Miscellaneous"
), n = c("106", "16920", "61216", "363698", "50797", "52715",
"174342", "9319", "92", "16928", "40920", "270963", "48605",
"34068", "114333", "4024", "3", "1536", "6793", "45146",
"7922", "5359", "27390", "1131", "12", "1311", "5431", "48107",
"6230", "5133", "21161", "505", "3619", "13", "2", "1", "19720",
"13", "10", "4", "96", "4643", "14534", "166664", "17178",
"17489", "30048", "5010", "96", "6904", "10463", "158060",
"15864", "20149", "24173", "2390", "12102", "7", "2", "1",
"10390", "5", "4", "2", "1", "11036", "329", "224", "2",
"2", "6936", "176", "85", "1", "15335", "55", "53", "48",
"14", "10292", "86", "47", "32", "11", "6559", "667", "631",
"419", "416", "4416", "336", "285", "105", "74", "2", "18",
"2", "18", "2", "86", "3151", "1", "14682", "77", "10", "9098",
"26", "2833", "5083", "2", "1", "1", "41051", "3", "45233",
"3", "10763", "44", "2", "6508", "2", "370", "265", "6",
"461", "86", "4", "5996", "2", "8826", "2", "1", "1", "503",
"5", "79", "3348", "742", "199", "989", "1", "473", "11",
"152", "3681", "363", "54", "804", "1702", "1", "1500", "2",
"1", "1", "1", "4868", "5", "2", "1", "5573", "1", "312",
"113", "3", "3", "42", "30", "6", "5", "371", "53", "19",
"312", "64", "23", "97", "121", "2", "3", "1", "3", "77")), row.names = c(NA,
-182L), class = c("tbl_df", "tbl", "data.frame"))
#[1]: https://i.stack.imgur.com/bDTWZ.png #[2]: https://i.stack.imgur.com/MaJ5r.png
您创建了一个包含 182 个 T 或 F 的列表,但您真正需要的是一个包含 24 个 T 或 F 的列表,因为有 24 行、24 组、24 条迹线plotly 是要显示还是不显示。
首先,您很好地按数据中的字段对绘图进行了分组。我有第一个情节的另一种变体 - 一次调用 plot_ly
并且仍然创建所有 24 条轨迹,就像你的循环一样。
首先我做了 Supplier_text
和排序因子,这样我就可以控制图例的顺序。
# this will keep the legend order in order
d2 <- dat %>%
mutate(Supplier_text = ordered(Supplier_text,
levels = rev(unique(dat$Supplier_text))))
然后我创建了 24 条轨迹。
(plt <- plot_ly(data = d2,
x = ~Date,
y = ~n,
color = ~Supplier_text,
type = "scatter",
mode = "lines"))
然后我更改了您为产品创建的过滤器。你有 24 条轨迹,现在你有 24 个 T 或 F 用于此过滤器。
# changed this so it is one for each trace, not one for each row
Parts_product_filter <- d2 %>% select(Supplier_text, Product) %>%
mutate(Smartphones = ifelse(Product == "Smartphones",T,F) %>% sapply(.,list),
TVs = ifelse(Product == "TVs",T, F) %>% sapply(.,list),
Monitors = ifelse(Product == "Monitors",T,F) %>% sapply(.,list),
Miscellaneous = ifelse(Product == "Miscellaneous",T,F) %>% sapply(.,list)) %>%
unique()
你的代码的其他部分保持不变,除了 plotly_object
的对象名称,现在 plt
在连接绘图的任何调用中(两个布局和 Chip_type
过滤器)。
更新替换
这仅包括“两者”按钮。
我在评论中回答你的问题,发现有些痕迹不对劲。所以当我解决这个问题时,我还添加了悬停,这样你就可以想象为什么会出现垂直线。请记住,n
是一个因素。 Plotly
不知道您要将哪个 n
值与右侧的哪个值连接,而不是通过 color.
当您将 n
设为数字字段时,plotly
会将这些值相加(除非您提供 plotly
其他划分内容的方式)。可悲的是,计算机无法读懂思想......但是......
我添加了一个 hovertemplate。如果您在图例中看到情节中没有的内容,那是 plotly
不知道该怎么做。如果将鼠标悬停在图上,您甚至可能会得到一个值,但没有线。我在最后有一些例子。
d2 <- dat %>%
mutate(Supplier_text = ordered(Supplier_text,
levels = rev(unique(dat$Supplier_text))),
Product = ordered(Product,
levels = sort(unique(dat$Product))),
Chip_type = ordered(Chip_type,
levels = sort(unique(dat$Chip_type))),
n = as.numeric(dat$n) %>% sort(decreasing = T) %>%
as.character() %>% ordered(., levels = unique(.))) %>%
arrange(n)
所有痕迹:
#------------- base plot ----------------
(plt <- d2 %>%
plot_ly(x = ~Date,
y = ~n,
color = ~Supplier_text,
type = 'scatter',
mode = 'lines',
text = ~Product,
hovertext = ~Chip_type,
visible = T
))
我意识到当我计算痕迹时,当绘图呈现时,我没有得到 45 条痕迹,我得到了更多!只有基本图有 24 条迹线。底座和组合键都有127条轨迹。
这就是我想出并验证更正的方式。
#------------- trace count ----------------
# I used length(plt$x$attrs) to confirm the number of traces
# -- that was a mistake!
# collect data, since it's not in the plotly object (errr)
pj = plotly_json(plt)
# read the JSON back
pjj = jsonlite::fromJSON(pj$x$data)
# number of traces:
nrow(pjj$data)
# [1] 24 # one trace for each color
组合痕迹:
#------------- add combination traces ----------------
# each of the possible button groups when both filters are opted
cmb = expand.grid(Product = levels(d2$Product),
Chip_type = levels(d2$Chip_type))
# create combo traces
invisible(
lapply(1:nrow(cmb), # filter for both
function(x){
d3 = d2 %>% filter(Product == cmb[x, 1] %>% toString(),
Chip_type == cmb[x, 2] %>% toString()) %>%
droplevels
if(nrow(d3) < 1) {
print(cmb[x, ]) # let me know what was skipped
return() # if no rows, don't make the trace
} # end if
plt <<- plt %>%
add_trace(inherit = F,
data = d2 %>%
filter(Product == cmb[x, 1] %>% toString(),
Chip_type == cmb[x, 2] %>% toString()),
x = ~Date, y = ~n,
color = ~Supplier_text,
type = 'scatter',
mode = 'lines',
text = ~Product,
hovertext = ~Chip_type,
hovertemplate = paste0("Products: %{text}",
"\nChips: %{hovertext}"),
visible = F #,
#inherit = F
)
})
)
cmb # validate
现在查看痕迹数:
#------------- combination traces updated trace count ----------------
# collect count
pj = plotly_json(plt)
# read the JSON back
pjj = jsonlite::fromJSON(pj$x$data)
# number of traces:
nrow(pjj$data)
# [1] 127 # whoa!
根据痕迹创建数据以确保 T/F 是正确的
#------------- trace data frame ----------------
# create data frame of the JSON content so that traces can be match with combos
plt.df = data.frame(nm = pjj$data$name, # this is Supplier_text
# valCount is the number of observations in the trace
valCount = unlist(map(pjj$data$x, ~length(.x))),
# whether it's visible (is it all or not?)
vis = pjj$data$visible)
# inspect what you expect
tail(plt.df)
按钮组合部分
#------------- set up for button for combos ----------------
tracs = d2 %>%
group_by(Product, Chip_type, Supplier_text) %>%
summarise(ct = n(), .groups = "drop") %>%
mutate(traces = 25:127)
# is the order the same in the plot?
tail(tracs, 10)
tail(plt.df, 10) # definitely not!
# check?
tracs %>% arrange(Chip_type) %>% tail(10)
# that's the right order
# update tracs' order
tracs <- tracs %>% arrange(Chip_type) %>%
mutate(traces = 25:nrow(plt.df)) # fix trace assignment
# double-check!
plt.df[25:35,]
tracs[1:11,]
# they aren't the same, but plotting groups are
# adjust cmb to be ordered before id trace to group combos
cmb <- cmb %>% arrange(Chip_type)
现在数据已对齐 (order-wise),我们需要准确找到哪些轨迹与哪些组相关。组中的每种颜色都会有一条轨迹(即,如果 Misc Titan 在 3 种不同颜色中有 5 进/5 出,则 Misc Titan 将有三个轨迹。
#--------------- collect group to trace number ----------------
# between cmb, d2, and the traces, the three vars - product, chip, and
# supplier text are ordered factors so the order will be the same
cmbo = invisible(
lapply(1:nrow(cmb),
function(x){
rs = tracs %>% filter(Product == cmb[x, 1] %>% toString(),
Chip_type == cmb[x, 2] %>% toString()) %>%
select(traces) %>% unlist() %>% unique(use.names = F)
list(traces = rs)
}) %>% setNames(paste0(cmb[, 1], " ", cmb[, 2])) # add the names
)# 32 start and stop points for the 103 traces
# check
cmbo[1:6]
现在按钮布局代码可以写成:
#---------------------- the button ----------------------
# now for the buttons...finally
# create the empty
raw_v <- rep(F, nrow(plt.df))
cButton <-
lapply(1:length(cmbo),
function(x){
traces <- cmbo[[x]][[1]] %>% unlist()
raw_v[traces] <- T
as.list(unlist(raw_v))
}) %>% setNames(names(cmbo))
# validate
length(cButton[[1]])
# [1] 127
length(cButton)
# [1] 32
# looks good
cmbBtn2 = lapply(1:length(cButton),
function(x){
label = names(cButton)[x] %>% gsub("\.", " ", x = .)
method = "restyle"
args = list("visible", cButton[[x]])
list(label = label, method = method, args = args)
})
按钮的all
部分
#------------- set up button for "all" ----------------
all = list(list(label = "All",
method = "restyle",
args = list("visible",
as.list(unlist(
c(rep(T, 24),
rep(F, nrow(plt.df) - 24)
)))) # end args
)) # end list list
现在把它们放在一起:
#---------------------- the layout ----------------------
Parts_legend <- list(
font = list(
family = "sans-serif",
size = 12,
color = "#000"),
title = list(text="<b> Delta previous month by Supplier - Absolute </b>"),
bgcolor = "#E2E2E2",
bordercolor = "#FFFFFF",
borderwidth = 2,
layout.legend = "constant",
traceorder = "grouped")
plt %>%
layout(legend = Parts_legend,
title = "by supplier delta previous month",
xaxis = list(title = 'Date'),
yaxis = list(title = 'Chip Volume'),
margin = list(l = 120, t = 100),
updatemenus = list(
list(
active = 0,
type = "dropdown",
y = 1.2,
direction = "down",
buttons = append(all, cmbBtn2)))
) # end layout
一些检查:
# check some of these for accuracy
d2 %>% filter(Product == "TVs", Chip_type == "PlainChip") # correct
d2 %>% filter(Product == "Miscellaneous", Chip_type == "BiMech") # correct
d2 %>% filter(Product == "Monitors", Chip_type == "Classic") # NOT right!
# there are 2 in and 2 out, but 1 in and 1 out match,
# the other's are different colors, so the line's not drawn
d2 %>% filter(Product == "TVs", Chip_type == "Micro") # not correct;
# that's because there is more in than out
最后一件事,我终于停下来了!垂直线——我放大了 'All'。这是同一图、相同缩放、相同 quasi-horizontal 线、相同 垂直 线的多个视图:
比方说,plotly
的所有规则都是 x、y 和颜色。它不关心其他数据,你没有那样绑定它(好吧,我没有)。