Полностью настроенный Санки; выравнивание узла по оси X, выпадение
Следующая диаграмма близка к тому, что я ищу, однако я хотел бы знать, возможно ли следующее:
- Выравнивание по левому краю узлов, а не выравнивание по оси x?, Так что, например, поток только с 2 узлами завершится на полпути по оси x, а не в точке x-max (в моей диаграмме Санки это не игрушка) выровнен по левому краю, однако я не могу понять разницу)
- Удалите ховертекст только на узлах (но не на ссылках). Я пробовал различные комбинации "метка", "текст", "значение", "процент", "имя", соединенные "+" ИЛИ "все", "нет" или "пропустить", но ничего из этого не помогло разница.
- Позаботьтесь о высадке с помощью NA, например, я не хочу видеть ссылку от SA на Drop (синий узел), но хочу видеть зеленую полосу в точке x=-1, чтобы показать, что один человек пошел в SA на их первый праздник и не было другого праздника. (Если я оставил source=SA и target=NA, график был пустым). Мой предложенный обходной путь будет заключаться в том, чтобы иначе раскрасить узлы DROP и SA-DROP белыми...
Пометили изображение желаемыми изменениями синего цвета.
require(dplyr); require(plotly); require(RColorBrewer); require(stringr)
# Summarise flow data
dat <- data.frame(customer = c(1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 5),
holiday_loc = c("SA", "SA", "AB", "SA", "SA", "SA", "SA", "AB", "AB", "SA", "SA", "SA")) %>%
group_by(customer) %>%
mutate(holiday_num = seq_along(customer),
source=paste0(holiday_loc, '_', holiday_num),
target = lead(source),
last_hol = ifelse(holiday_num == n(), 'Y', 'N')) %>%
filter(last_hol== 'N'| holiday_num == 1) %>%
select(-last_hol)
sank_links <- dat %>%
group_by(source, target) %>%
summarise(n=n()) %>%
mutate(target=ifelse(is.na(target), "DROP", target)) # is there another option here?
# obtain colours for nodes
f <- function(pal) brewer.pal(brewer.pal.info[pal, "maxcolors"], pal)
cols <- f("Set1")
# set up nodes
sank_nodes <- data.frame(
name = factor(sort(unique(c(as.character(sank_links$source),
as.character(sank_links$target)))))
) %>%
mutate(label=sub("_[0-9]$", "", name),
# for some unknown reason, plotly allows only three labels to be the same
label_pad=sub("_[1-3]$", "", name),
label_pad=sub("_[4-6]$", " ", label_pad)) %>%
arrange(label) %>%
mutate(color = cols[cumsum(1-duplicated(label))])
# update links to get index of node and name (without holiday_num)
sank_links <- sank_links %>%
mutate(source_num = match(source, sank_nodes$name) -1 ,
source_name = str_replace(source, "_[0-9]$", ""),
target_num = match(target, sank_nodes$name) - 1,
target_name = str_replace(target, "_[0-9]$", ""))
# diagram
p <- plot_ly(
type = "sankey",
domain = c(
x = c(0,1),
y = c(0,1)
),
orientation = "h",
valueformat = ".0f",
valuesuffix = "Customers",
arrangement="fixed",
node = list(
label = sank_nodes$label_pad,
color = sank_nodes$color,
pad = 15,
thickness = 15,
line = list(
color = "black",
width = 0.5
)
),
link = list(
source = sank_links$source_num,
target = sank_links$target_num,
value = sank_links$n
)
) %>%
layout(
title = "",
font = list(
size = 10
),
xaxis = list(showgrid = F, zeroline = F),
yaxis = list(showgrid = F, zeroline = F)
)
p
РЕДАКТИРОВАТЬ: я изначально не знал, как пометить ось X с перерывами, соответствующими узлам и обеспечить заголовок по оси X; код выглядит следующим образом:
%>%
layout(
title = "",
font = list(
size = 10
),
xaxis = list(showgrid = F, zeroline = F, title="Holiday Number", tickvals=-1:4, ticktext=1:6),
yaxis = list(showgrid = F, zeroline = F, showticklabels=FALSE)
)
Источник: https://plot.ly/r/reference/
1 ответ
Фактически, вы можете вручную переопределить положение узлов (все или только те, которые вам нужны).
Вы можете сделать это в списке узлов, добавив вектор для оси x и вектор для оси y с положениями узлов, которые вы хотите изменить. Если вы хотите сохранить узел в той же позиции, просто добавьте NA к этой векторной позиции.
node = list(
label = sank_nodes$label_pad,
color = sank_nodes$color,
pad = 15,
thickness = 15,
line = list(
color = "black",
width = 0.5
),
x = c(NA, 0.35, 0.65, NA, NA, NA, NA, NA),
y = c(NA, 0.10, 0.42, NA, NA, NA, NA, NA)
)
Вы не можете изменить положение узлов в Plotly, но если вы измените расположение с "фиксированного" на "произвольную", вы можете перемещать узлы вручную в любом месте, где вы хотите, после визуализации диаграммы. Тем не менее, это должно быть сделано вручную пользователем каждый раз при визуализации диаграммы. На данный момент нет способа упорядочить узлы в скрипте Plotly.
Собственно, это вполне возможно.
import plotly.graph_objects as go
fig = go.Figure(go.Sankey(
arrangement = "snap",
node = {
"label": ["A", "B", "C", "D", "E", "F"],
"x": [0.2, 0.1, 0.5, 0.7, 0.3, 0.5],
"y": [0.7, 0.5, 0.2, 0.4, 0.2, 0.3],
'pad':10}, # 10 Pixels
link = {
"source": [0, 0, 1, 2, 5, 4, 3, 5],
"target": [5, 3, 4, 3, 0, 2, 2, 3],
"value": [1, 2, 1, 1, 1, 1, 1, 2]}))
fig.show()
Код с сайта plotly.com.