Skip to content

fix sankey trace x/y node fields #309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 9 additions & 107 deletions docs/book/src/recipes/basic_charts/sankey_diagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,114 +15,16 @@ use rand_distr::{Distribution, Normal, Uniform};
The `to_inline_html` method is used to produce the html plot displayed in this page.

## Constructing a basic Sankey diagram
```rust
let trace = Sankey::new()
.orientation(Orientation::Horizontal)
.node(
Node::new()
.pad(15)
.thickness(30)
.line(SankeyLine::new().color(NamedColor::Black).width(0.5))
.label(vec!["A1", "A2", "B1", "B2", "C1", "C2"])
.color_array(vec![
NamedColor::Blue,
NamedColor::Blue,
NamedColor::Blue,
NamedColor::Blue,
NamedColor::Blue,
NamedColor::Blue,
]),
)
.link(
Link::new()
.value(vec![8, 4, 2, 8, 4, 2])
.source(vec![0, 1, 0, 2, 3, 3])
.target(vec![2, 3, 3, 4, 4, 5]),
);
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:basic_sankey_diagram}}
```

let layout = Layout::new()
.title("Basic Sankey".into())
.font(Font::new().size(10));
{{#include ../../../../../examples/basic_charts/output/inline_basic_sankey_diagram.html}}

let mut plot = Plot::new();
plot.add_trace(trace);
plot.set_layout(layout);

if show {
plot.show();
}
}
## Skankey diagram with defined node position
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:custom_node_sankey_diagram}}
```
<div id="basic-sankey-diagram" class="plotly-graph-div" style="height:100%; width:100%;"></div>
<script type="text/javascript">
window.PLOTLYENV=window.PLOTLYENV || {};
if (document.getElementById("basic-sankey-diagram")) {
Plotly.newPlot('basic-sankey-diagram', {
"data": [
{
"type": "sankey",
"orientation": "h",
"node": {
"color": [
"blue",
"blue",
"blue",
"blue",
"blue",
"blue"
],
"label": [
"A1",
"A2",
"B1",
"B2",
"C1",
"C2"
],
"line": {
"color": "black",
"width": 0.5
},
"pad": 15,
"thickness": 30
},
"link": {
"source": [
0,
1,
0,
2,
3,
3
],
"target": [
2,
3,
3,
4,
4,
5
],
"value": [
8,
4,
2,
8,
4,
2
]
}
}
],
"layout": {
"title": {
"text": "Basic Sankey"
},
"font": {
"size": 10
}
},
"config": {}
});
};
</script>

{{#include ../../../../../examples/basic_charts/output/inline_custom_node_sankey_diagram.html}}
39 changes: 39 additions & 0 deletions examples/basic_charts/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,44 @@ fn basic_sankey_diagram(show: bool, file_name: &str) {
}
// ANCHOR_END: basic_sankey_diagram

// ANCHOR: custom_node_sankey_diagram
fn custom_node_sankey_diagram(show: bool, file_name: &str) {
// https://plotly.com/javascript/sankey-diagram/#basic-sankey-diagram
let trace = Sankey::new()
.orientation(Orientation::Horizontal)
.arrangement(plotly::sankey::Arrangement::Snap)
.node(
Node::new()
.pad(15)
.thickness(30)
.line(SankeyLine::new().color(NamedColor::Black).width(0.5))
.label(vec!["A", "B", "C", "D", "E", "F"])
.x(vec![0.2, 0.1, 0.5, 0.7, 0.3, 0.5])
.y(vec![0.2, 0.1, 0.5, 0.7, 0.3, 0.5])
.pad(20),
)
.link(
Link::new()
.source(vec![0, 0, 1, 2, 5, 4, 3, 5])
.target(vec![5, 3, 4, 3, 0, 2, 2, 3])
.value(vec![1, 2, 1, 1, 1, 1, 1, 2]),
);

let layout = Layout::new()
.title("Define Node Position")
.font(Font::new().size(10));

let mut plot = Plot::new();
plot.add_trace(trace);
plot.set_layout(layout);

let path = write_example_to_html(&plot, file_name);
if show {
plot.show_html(path);
}
}
// ANCHOR_END: custom_node_sankey_diagram

// ANCHOR: table_chart
fn table_chart(show: bool, file_name: &str) {
let trace = Table::new(
Expand Down Expand Up @@ -1006,6 +1044,7 @@ fn main() {

// Sankey Diagrams
basic_sankey_diagram(false, "basic_sankey_diagram");
custom_node_sankey_diagram(false, "custom_node_sankey_diagram");

// Pie Charts
basic_pie_chart(false, "basic_pie_chart");
Expand Down
20 changes: 12 additions & 8 deletions plotly/src/traces/sankey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ pub struct Node {
hover_template: Option<Dim<String>>,
label: Option<Vec<String>>,
line: Option<Line>,
/// Sets the padding (in px) between the `nodes`.
pad: Option<usize>,
/// Sets the thickness (in px) of the `nodes`.
thickness: Option<usize>,
x: Option<f64>,
y: Option<f64>,
/// The normalized horizontal position of the node.
x: Option<Vec<f64>>,
/// The normalized vertical position of the node.
y: Option<Vec<f64>>,
}

impl Node {
Expand Down Expand Up @@ -115,12 +119,12 @@ impl Node {
self
}

pub fn x(mut self, x: f64) -> Self {
pub fn x(mut self, x: Vec<f64>) -> Self {
self.x = Some(x);
self
}

pub fn y(mut self, y: f64) -> Self {
pub fn y(mut self, y: Vec<f64>) -> Self {
self.y = Some(y);
self
}
Expand Down Expand Up @@ -509,8 +513,8 @@ mod tests {
.line(Line::new())
.pad(5)
.thickness(10)
.x(0.5)
.y(0.25);
.x(vec![0.5])
.y(vec![0.25]);
let expected = json!({
"color": ["blue"],
"hoverinfo": "all",
Expand All @@ -519,8 +523,8 @@ mod tests {
"line": {},
"pad": 5,
"thickness": 10,
"x": 0.5,
"y": 0.25
"x": [0.5],
"y": [0.25]
});

assert_eq!(to_value(node).unwrap(), expected)
Expand Down
Loading