plotters-rs / plotters

A rust drawing library for high quality data plotting for both WASM and native, statically and realtimely 🦀 📈🚀
https://plotters-rs.github.io/home/
MIT License
3.89k stars 281 forks source link

Add support for evcxr (Rust Jupyter kernel) #6

Closed zacps closed 5 years ago

zacps commented 5 years ago

This requires implementing a method called evcxr_display which returns HTML.

See: https://github.com/google/evcxr/blob/master/evcxr_jupyter/README.md#custom-output

38 commented 5 years ago

My guess is if we return an SVG and wrap it in a HTML file, that would work?

38 commented 5 years ago

@zacps Also, would you please give me some instructions on how to use evcxr with Jupyter.

I just tried the page, it shows compile errors even with the sample on that page.

zacps commented 5 years ago

Could you paste the error?

What jupyter and rust toolchain version you're using would also be helpful.

38 commented 5 years ago
use std::fmt::Debug;

pub struct Matrix<T> {pub values: Vec<T>, pub row_size: usize}

impl<T: Debug> Matrix<T> {

    pub fn evcxr_display(&self) {

        let mut html = String::new();

        html.push_str("<table>");

        for r in 0..(self.values.len() / self.row_size) {

            html.push_str("<tr>");

            for c in 0..self.row_size {

                html.push_str("<td>");

                html.push_str(&format!("{:?}", self.values[r * self.row_size + c]));

                html.push_str("</td>");

            }

            html.push_str("</tr>");

        }

        html.push_str("</table>");

        println!("EVCXR_BEGIN_CONTENT text/html\n{}\nEVCXR_END_CONTENT", html);

    }

}

let m = Matrix {values: vec![1,2,3,4,5,6,7,8,9], row_size: 3};

m

Compilation failed, but no parsable errors were found. STDERR:
   Compiling user_code_1 v1.0.0 (/tmp/.tmpndVY1C/user_code_1)
error[E0308]: mismatched types
  --> src/lib.rs:21:60
   |
21 | evcxr_variable_store.put_variable::<String>(stringify!(m), m);
   |                                                            ^ expected struct `std::string::String`, found struct `user_code_0::Matrix`
   |
   = note: expected type `std::string::String`
              found type `user_code_0::Matrix<{integer}>`

error[E0277]: the trait bound `user_code_0::Matrix<{integer}>: std::marker::Copy` is not satisfied
  --> src/lib.rs:22:22
   |
22 | evcxr_variable_store.assert_copy_type(m);
   |                      ^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `user_code_0::Matrix<{integer}>`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: Could not compile `user_code_1`.

To learn more, run the command again with --verbose.

STDOUT:

The Rust version is

$ rustc --version
rustc 1.37.0-nightly (37d001e4d 2019-05-29)
zacps commented 5 years ago

I can reproduce, it seems to be broken on nightly.

Works for me on stable (rustup default stable).

38 commented 5 years ago
:dep plotters = { git = "https://github.com/38/plotters", default_features = false, features = ["evcxr"] }
extern crate plotters;
use plotters::prelude::*;

let figure = evcxr_figure((640, 480), |root| {
    root.fill(&White);
    let mut chart = ChartBuilder::on(&root)
        .caption("y=x^2", &("Arial", 50).into_font())
        .margin(5)
        .x_label_area_size(30)
        .y_label_area_size(30)
        .build_ranged(-1f32..1f32, -0.1f32..1f32)?;

    chart.configure_mesh().draw()?;

    chart.draw_series(LineSeries::new(
        (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
        &Red,
    )).unwrap()
        .label("y = x^2")
        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &Red));

    chart.configure_series_labels()
        .background_style(&White.mix(0.8))
        .border_style(&Black)
        .draw()?;
    Ok(())
});
figure

You should be able to use this.