Reputation: 389
I have below code, which is to add annonation for each column in the sankey chart.
library("plotly")
library("ggplot2")
library("dplyr")
library("xml2")
library("htmlwidgets")
a <- read.csv(header = TRUE, text = "date,Data Center,Customer,companyID,source,target,value
")
node_names <- union(a$source, a$target)
node_names <- node_names[order(sub('.*_', '', node_names))]
nodes <- data.frame(name = node_names)
links <- data.frame(source = match(a$source, node_names) - 1,
target = match(a$target, node_names) - 1,
value = a$value)
definePosition <- function(nodeList){
# nodeList = node_names
# unique name endings
endings = unique(sub('.*_', '', nodeList))
# define intervals
steps = 1/length(endings)
# x-values for each unique name ending
# for input as node position
nodes_x = {}
xVal = 0
for (e in endings) {
nodes_x[e] = xVal
xVal = xVal + steps
}
# x and y values in list form
x_values <- 0
y_values <- 0
i =1
for (n in nodeList) {
last = sub('.*_', '', n)
x_values[i] = nodes_x[last]
y_values[i] = 0.001 * length(x_values)
i = i + 1
}
return(list(x_values, y_values))
}
position = definePosition(node_names)
node_x = position[[1L]]
node_y = position[[2L]]
#Plot
plot_ly(type='sankey',
orientation = "h",
arrangement = "snap",
node = list (
label = node_names,
x = node_x,
y = node_y,
color = "steelblue",
pad = 15,
thinkness = 15,
line = list(color = "black", width = 0.5)),
link = list(source = links$source, target = links$target, value = links$value, color = "gainsboro")) %>%
add_annotations(x=unique(node_x)[1],y=1,xref = "x",yref = "paper",text = "<b>step1</b>",xanchor = 'left',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[2],y=1,xref = "x",yref = "paper",text = "<b>step2</b>",xanchor = 'left',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[3],y=1,xref = "x",yref = "paper",text = "<b>step3</b>",xanchor = 'left',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[4],y=1,xref = "x",yref = "paper",text = "<b>step4</b>",xanchor = 'left',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[5],y=1,xref = "x",yref = "paper",text = "<b>step5</b>",xanchor = 'left',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[6],y=1,xref = "x",yref = "paper",text = "<b>step6</b>",xanchor = 'left',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[7],y=1,xref = "x",yref = "paper",text = "<b>step7</b>",xanchor = 'left',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[8],y=1,xref = "x",yref = "paper",text = "<b>step8</b>",xanchor = 'left',showarrow = F, align = "center") %>%
layout(
title = "<b>Opportunity Marketing User Behavior Monitor(Prod environment)</b>",
font = list(
size = 10,
color = 'grey'
),
margin = list(
l = 30,
r = 50,
b = 50,
t = 100,
pad = 20
),
xaxis = list(showgrid = F, zeroline = F, visiable = F, showticklabels = F),
yaxis = list(showgrid = F, zeroline = F, visiable = F, showticklabels = F)
)
but after running the code, the annonation added is not aligned with each column. My thought is to get the x-axis position for each column, and then assign to x parameters for each add_annonation. But how to know the x-axis value for each column??
Upvotes: 0
Views: 587
Reputation: 288
It appears that your definePosition() function is putting your node labels in the expected places. It is doing its job. However, it is the nodes that are not appearing where they should.
You are attempting to fix the node positions using calculated node_x
and node_y
vectors. However, plotly's handling of manual node positions is finicky and a bit opaque. In some cases it appears to override manual positions. I have found that in your situation, omitting one or both of the arguments x
or y
in node
will align your nodes where expected. For example:
plot_ly(type='sankey',
orientation = "h",
arrangement = "snap",
node = list (
label = node_names,
# x = node_x, # No longer setting node.x manually
y = node_y,
color = "steelblue",
pad = 15,
thinkness = 15,
line = list(color = "black", width = 0.5)),
link = list(source = links$source, target = links$target, value = links$value, color = "gainsboro")) %>%
add_annotations(x=unique(node_x)[1],y=1,xref = "x",yref = "paper",text = "<b>step1</b>",xanchor = 'right',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[2],y=1,xref = "x",yref = "paper",text = "<b>step2</b>",xanchor = 'right',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[3],y=1,xref = "x",yref = "paper",text = "<b>step3</b>",xanchor = 'right',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[4],y=1,xref = "x",yref = "paper",text = "<b>step4</b>",xanchor = 'right',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[5],y=1,xref = "x",yref = "paper",text = "<b>step5</b>",xanchor = 'right',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[6],y=1,xref = "x",yref = "paper",text = "<b>step6</b>",xanchor = 'right',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[7],y=1,xref = "x",yref = "paper",text = "<b>step7</b>",xanchor = 'right',showarrow = F, align = "center") %>%
add_annotations(x=unique(node_x)[8],y=1,xref = "x",yref = "paper",text = "<b>step8</b>",xanchor = 'right',showarrow = F, align = "center") %>%
layout(
title = "<b>Opportunity Marketing User Behavior Monitor(Prod environment)</b>",
font = list(
size = 10,
color = 'grey'
),
margin = list(
l = 30,
r = 50,
b = 50,
t = 100,
pad = 20
),
xaxis = list(showgrid = F, zeroline = F, visiable = F, showticklabels = F),
yaxis = list(showgrid = F, zeroline = F, visiable = F, showticklabels = F)
)
This issue bugs me a lot; I ran into something similar before which was why your question interested me (Why are fixed positions for nodes in a plotly sankey graph being overridden or ignored?). I've opened an issue about it on the plotly.r github as well.
Upvotes: 1