Finishing Touches for Visualisation

Preamble

In [2]:
extern crate plotly;
extern crate nanoid;
extern crate darn;

use plotly::{Plot, Scatter, Layout};
use plotly::common::{Mode, Anchor, Orientation, Title};
use plotly::layout::{Legend, Margin, Axis};
use nanoid::nanoid;
use std::fs;

Plotly Workaround Function

In the last section, we improved upon our Plotly workaround to get our plots to appear within our notebooks. All that's left now is to separate our workaround into a function so that we can re-use it throughout the rest of this book. We'll name this function show_plot()

In [3]:
fn show_plot(plot: Plot) { 
    let plotly_file = "temp_plot.html";
    plot.to_html(plotly_file);
    let plotly_contents = fs::read_to_string(plotly_file).unwrap();
    fs::remove_file(plotly_file);

    let start_bytes = plotly_contents
        .find("<div id='plotly-html-element' class='plotly-graph-div'")
        .unwrap_or(0);
    
    let end_bytes = plotly_contents
        .find("\n</div>\n</body>\n</html>")
        .unwrap_or(plotly_contents.len());
    
    println!("EVCXR_BEGIN_CONTENT text/html\n{}\nEVCXR_END_CONTENT",
    format!("<div>{}</div>",
        &plotly_contents[start_bytes..end_bytes]
        .replace("plotly-html-element", Box::leak(nanoid!().into_boxed_str()))));
}

Now let's use the same example code from the previous sections and use our function above to display the plot. This time, we're going to use the Layout struct and specify some customisations. This will reduce the padding on our plot, change the positioning of the legend, and label the axes. This is not a necessary step, however, the output should look much nicer.

In [4]:
let layout = Layout::new()
    .xaxis(Axis::new().title(Title::new("x axis")))
    .yaxis(Axis::new().title(Title::new("y axis")))
    .margin(Margin::new().top(0).bottom(40).left(40).right(10))
    .legend(Legend::new().x(0.5).y(1.1)
    .orientation(Orientation::Horizontal).x_anchor(Anchor::Center));

let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![10, 15, 13, 17])
    .name("trace1")
    .mode(Mode::Markers);
let trace2 = Scatter::new(vec![2, 3, 4, 5], vec![16, 5, 11, 9])
    .name("trace2")
    .mode(Mode::Lines);
let trace3 = Scatter::new(vec![1, 2, 3, 4], vec![12, 9, 15, 12])
    .name("trace3");

let mut plot = Plot::new();

plot.set_layout(layout);
plot.add_trace(trace1);
plot.add_trace(trace2);
plot.add_trace(trace3);

To display our plot, we can pass the plot variable to our show_plot() function.

In [5]:
show_plot(plot);
Out[5]: