|
1 |
| -# `ndarray` Support |
| 1 | +# `ndarray` Support |
| 2 | + |
| 3 | +To enable [ndarray](https://github.com/rust-ndarray/ndarray) support in [Plotly.rs](https://github.com/igiagkiozis/plotly) add the following feature to your `Cargo.toml` file: |
| 4 | +```toml |
| 5 | +[dependencies] |
| 6 | +plotly = { version = ">=0.6.0", features = ["plotly_ndarray"] } |
| 7 | +``` |
| 8 | + |
| 9 | +This extends the [Plotly.rs](https://github.com/igiagkiozis/plotly) API in two ways: |
| 10 | +* `Scatter` traces can now be created using the `Scatter::from_ndarray` constructor, |
| 11 | +* and also multiple traces can be created with the `Scatter::to_traces` method. |
| 12 | + |
| 13 | +The full source code for the examples below can be found [here](https://github.com/igiagkiozis/plotly/blob/master/plotly/examples/ndarray_support.rs). |
| 14 | + |
| 15 | +## `ndarray` Traces |
| 16 | + |
| 17 | +The following imports have been used to produce the plots below: |
| 18 | + |
| 19 | +```rust |
| 20 | +use plotly::common::{Mode}; |
| 21 | +use plotly::{Plot, Scatter}; |
| 22 | +use ndarray::{Array, Ix1, Ix2}; |
| 23 | +use plotly::ndarray::ArrayTraces; |
| 24 | +``` |
| 25 | + |
| 26 | + |
| 27 | +### Single Trace |
| 28 | +```rust |
| 29 | +fn single_ndarray_trace(show: bool) { |
| 30 | + let n: usize = 11; |
| 31 | + let t: Array<f64, Ix1> = Array::range(0., 10., 10. / n as f64); |
| 32 | + let ys: Array<f64, Ix1> = t.iter().map(|v| (*v).powf(2.)).collect(); |
| 33 | + |
| 34 | + let trace = Scatter::from_array(t, ys).mode(Mode::LinesMarkers); |
| 35 | + |
| 36 | + let mut plot = Plot::new(); |
| 37 | + plot.add_trace(trace); |
| 38 | + if show { |
| 39 | + plot.show(); |
| 40 | + } |
| 41 | + println!("{}", plot.to_inline_html(Some("single_ndarray_trace"))); |
| 42 | +} |
| 43 | +``` |
| 44 | +<div id="single_ndarray_trace" class="plotly-graph-div" style="height:100%; width:100%;"></div> |
| 45 | +<script type="text/javascript"> |
| 46 | + window.PLOTLYENV=window.PLOTLYENV || {}; |
| 47 | + if (document.getElementById("single_ndarray_trace")) { |
| 48 | + var d3 = Plotly.d3; |
| 49 | + var image_element= d3.select('#image-export'); |
| 50 | + var trace_0 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[0.0,0.8264462809917354,3.305785123966942,7.438016528925619,13.223140495867767,20.661157024793383,29.752066115702476,40.49586776859504,52.89256198347107,66.94214876033058,82.64462809917353]}; |
| 51 | +var data = [trace_0]; |
| 52 | +var layout = {}; |
| 53 | + Plotly.newPlot('single_ndarray_trace', data, layout, {"responsive": true}); |
| 54 | + }; |
| 55 | +</script> |
| 56 | + |
| 57 | +### Multiple Traces |
| 58 | +To display a `2D` array (`Array<_, Ix2>`) you can use the `Scatter::to_traces` method. The first argument of the method represents the common axis for the traces (`x` axis) whilst the second argument contains a collection of traces. At this point it should be noted that there is some ambiguity when passing a `2D` array; namely are the traces arranged along the columns or the rows of the matrix? This ambiguity is resolved by the third argument of the `Scatter::to_traces` method. If that argument is set to `ArrayTraces::OverColumns` then the library assumes that every column represents an individual trace, alternatively if this is set to `ArrayTraces::OverRows` the assumption is that every row represents a trace. |
| 59 | + |
| 60 | +To illustrate this distinction consider the following examples: |
| 61 | +```rust |
| 62 | +fn multiple_ndarray_traces_over_columns(show: bool) { |
| 63 | + let n: usize = 11; |
| 64 | + let t: Array<f64, Ix1> = Array::range(0., 10., 10. / n as f64); |
| 65 | + let mut ys: Array<f64, Ix2> = Array::zeros((11, 11)); |
| 66 | + let mut count = 0.; |
| 67 | + for mut row in ys.gencolumns_mut() { |
| 68 | + for index in 0..row.len() { |
| 69 | + row[index] = count + (index as f64).powf(2.); |
| 70 | + } |
| 71 | + count += 1.; |
| 72 | + } |
| 73 | + |
| 74 | + let traces = |
| 75 | + Scatter::default() |
| 76 | + .mode(Mode::LinesMarkers) |
| 77 | + .to_traces(t, ys, ArrayTraces::OverColumns); |
| 78 | + |
| 79 | + let mut plot = Plot::new(); |
| 80 | + plot.add_traces(traces); |
| 81 | + if show { |
| 82 | + plot.show(); |
| 83 | + } |
| 84 | + println!("{}", plot.to_inline_html(Some("multiple_ndarray_traces_over_columns"))); |
| 85 | +} |
| 86 | +``` |
| 87 | +<div id="multiple_ndarray_traces_over_columns" class="plotly-graph-div" style="height:100%; width:100%;"></div> |
| 88 | +<script type="text/javascript"> |
| 89 | + window.PLOTLYENV=window.PLOTLYENV || {}; |
| 90 | + if (document.getElementById("multiple_ndarray_traces_over_columns")) { |
| 91 | + var d3 = Plotly.d3; |
| 92 | + var image_element= d3.select('#image-export'); |
| 93 | + var trace_0 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[0.0,1.0,4.0,9.0,16.0,25.0,36.0,49.0,64.0,81.0,100.0]}; |
| 94 | +var trace_1 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[1.0,2.0,5.0,10.0,17.0,26.0,37.0,50.0,65.0,82.0,101.0]}; |
| 95 | +var trace_2 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[2.0,3.0,6.0,11.0,18.0,27.0,38.0,51.0,66.0,83.0,102.0]}; |
| 96 | +var trace_3 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[3.0,4.0,7.0,12.0,19.0,28.0,39.0,52.0,67.0,84.0,103.0]}; |
| 97 | +var trace_4 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[4.0,5.0,8.0,13.0,20.0,29.0,40.0,53.0,68.0,85.0,104.0]}; |
| 98 | +var trace_5 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[5.0,6.0,9.0,14.0,21.0,30.0,41.0,54.0,69.0,86.0,105.0]}; |
| 99 | +var trace_6 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[6.0,7.0,10.0,15.0,22.0,31.0,42.0,55.0,70.0,87.0,106.0]}; |
| 100 | +var trace_7 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[7.0,8.0,11.0,16.0,23.0,32.0,43.0,56.0,71.0,88.0,107.0]}; |
| 101 | +var trace_8 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[8.0,9.0,12.0,17.0,24.0,33.0,44.0,57.0,72.0,89.0,108.0]}; |
| 102 | +var trace_9 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[9.0,10.0,13.0,18.0,25.0,34.0,45.0,58.0,73.0,90.0,109.0]}; |
| 103 | +var trace_10 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[10.0,11.0,14.0,19.0,26.0,35.0,46.0,59.0,74.0,91.0,110.0]}; |
| 104 | +var data = [trace_0,trace_1,trace_2,trace_3,trace_4,trace_5,trace_6,trace_7,trace_8,trace_9,trace_10]; |
| 105 | +var layout = {}; |
| 106 | + Plotly.newPlot('multiple_ndarray_traces_over_columns', data, layout, {"responsive": true}); |
| 107 | + }; |
| 108 | +</script> |
| 109 | + |
| 110 | +Replacing `ArrayTraces::OverColumns` with `ArrayTraces::OverRows` results in the following: |
| 111 | + |
| 112 | +<div id="multiple_ndarray_traces_over_rows" class="plotly-graph-div" style="height:100%; width:100%;"></div> |
| 113 | +<script type="text/javascript"> |
| 114 | + window.PLOTLYENV=window.PLOTLYENV || {}; |
| 115 | + if (document.getElementById("multiple_ndarray_traces_over_rows")) { |
| 116 | + var d3 = Plotly.d3; |
| 117 | + var image_element= d3.select('#image-export'); |
| 118 | + var trace_0 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0]}; |
| 119 | +var trace_1 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0]}; |
| 120 | +var trace_2 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0]}; |
| 121 | +var trace_3 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]}; |
| 122 | +var trace_4 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0]}; |
| 123 | +var trace_5 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0]}; |
| 124 | +var trace_6 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0]}; |
| 125 | +var trace_7 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[49.0,50.0,51.0,52.0,53.0,54.0,55.0,56.0,57.0,58.0,59.0]}; |
| 126 | +var trace_8 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[64.0,65.0,66.0,67.0,68.0,69.0,70.0,71.0,72.0,73.0,74.0]}; |
| 127 | +var trace_9 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[81.0,82.0,83.0,84.0,85.0,86.0,87.0,88.0,89.0,90.0,91.0]}; |
| 128 | +var trace_10 = {"type":"scatter","mode":"lines+markers","x":[0.0,0.9090909090909091,1.8181818181818181,2.727272727272727,3.6363636363636362,4.545454545454545,5.454545454545454,6.363636363636363,7.2727272727272725,8.181818181818182,9.09090909090909],"y":[100.0,101.0,102.0,103.0,104.0,105.0,106.0,107.0,108.0,109.0,110.0]}; |
| 129 | +var data = [trace_0,trace_1,trace_2,trace_3,trace_4,trace_5,trace_6,trace_7,trace_8,trace_9,trace_10]; |
| 130 | +var layout = {}; |
| 131 | + Plotly.newPlot('multiple_ndarray_traces_over_rows', data, layout, {"responsive": true}); |
| 132 | + }; |
| 133 | +</script> |
0 commit comments