Movatterモバイル変換


[0]ホーム

URL:


Plotters Tutorial with Jupyter

This is a interactive tutorial forPlotters drawing library. If you are looking at the static HTML version and want to try the interactive version. Please follow the steps:

For Ubuntu/Debian users

# Install Jupyter notebooksudo apt install libzmq3-dev jupyter-notebookcargo install evcxr_jupyterevcxr_jupyter --install# Get the notebookgit clone https://github.com/38/plotters-doc-datacd plotteres-doc-datajupyter notebook

For OSX users

# Install Jupyter notebookbrew install zeromq pkg-configcargo install evcxr_jupyterevcxr_jupyter --install# Get the notebookgit clone https://github.com/38/plotters-doc-datacd plotteres-doc-datajupyter notebook

You can also download the latest notebook fromhttps://raw.githubusercontent.com/38/plotters-doc-data/master/evcxr-jupyter-integration.ipynb, thus you don't have to clone the entire data repo.

Get Started

In order to usePlotters injupyter-evcxr, you need both Jupyter and evcxr installed.Checkhttps://github.com/google/evcxr for the instructions.

To use Plotters withjupyter-evcxr, you need to import it using the following code:

In [2]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}

Becauseevcxr uses only SVG images and all types of series, so we don't need other types of backend. So we should put

default_features = false, features = ["evcxr", "all_series"]

Make the compilation faster. Sinceevcxr shares all the artifacts among cells, after the first time we haveplotters compiled, it should be faster after.

Plotters evcxr integration overview

To use plotters, the most convenient way is importing everything defined in theprelude module.It will importevcxr_figure function forevcxr integration.

Note: Currently evcxr doesn't work with nightly rust, so please make sure you are using a stable rust

In [4]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;// Import all the plotters prelude functionsuseplotters::prelude::*;// To create a figure that can be displayed in Jupyter notebook, use evcxr_figure function.// The first param is the resolution of the figure.// The second param is the closure that performes the drawing.evcxr_figure((300,100),|root|{// Do the drawingsroot.fill(&BLUE)?;// Tell plotters that everything is okOk(())})
Out[4]:

Hello World

In [5]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((320,50),|root|{root.fill(&GREEN)?;root.draw(&Text::new("Hello World from Plotters!",(15,15),("Arial",20).into_font()))?;Ok(())})
Out[5]:
Hello World from Plotters!

Sub- Drawing Areas

One of the very important features is,Plotters allows drawing multiple charts in a single figure. And this is done by having sub-drawing-areas. The root drawing area is able to be splitted into smaller drawing areas, and you can always do more fine-grained splits as well.

In [6]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;useplotters::coord::Shift;pubfnsierpinski_carpet(depth:u32,drawing_area:&DrawingArea<SVGBackend,Shift>)->Result<(),Box<dynstd::error::Error>>{ifdepth>0{letsub_areas=drawing_area.split_evenly((3,3));for(idx,sub_area)in(0..).zip(sub_areas.iter()){ifidx==4{sub_area.fill(&WHITE)?;}else{sierpinski_carpet(depth-1,sub_area)?;}}}Ok(())}evcxr_figure((4800,4800),|root|{root.fill(&BLACK)?;sierpinski_carpet(5,&root)}).style("width: 200px")/* You can add CSS style to the result */
Out[6]:

Chart Context

Plotters is designed for drawing charts, plots, etc. This example demonstrate how to usePlotters chart specific APIs to draw a chart, including, labels, axis, meshes, etc. To draw a chart on the drawin area, you need to create a chart context and do some configuration.

In [7]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,240),|root|{// The following code will create a chart contextletmutchart=ChartBuilder::on(&root).caption("Hello Plotters Chart Context!",("Arial",20).into_font()).build_cartesian_2d(0f32..1f32,0f32..1f32)?;// Then we can draw a series on it!chart.draw_series((1..10).map(|x|{letx=xasf32/10.0;Circle::new((x,x),5,&RED)}))?;Ok(())}).style("width:60%")
Out[7]:
Hello Plotters Chart Context!

Adding Common Chart Components

We can also makePlotters draws common components for us, such as, meshes, axis, legend. In this section, we demonstrate how to do that.

The following code shows how we add mesh to the chart.

In [8]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,480),|root|{// The following code will create a chart contextletmutchart=ChartBuilder::on(&root).caption("Chart Context with Mesh",("Arial",20).into_font()).build_cartesian_2d(0f32..1f32,0f32..1f32)?;chart.configure_mesh().draw()?;Ok(())}).style("width: 60%")
Out[8]:
Chart Context with Mesh

Then we can add axis to the chart.

In [9]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,480),|root|{// The following code will create a chart contextletmutchart=ChartBuilder::on(&root).caption("Chart Context with Mesh and Axis",("Arial",20).into_font()).x_label_area_size(40).y_label_area_size(40).build_cartesian_2d(0f32..1f32,0f32..1f32)?;chart.configure_mesh().draw()?;Ok(())}).style("width: 60%")
Out[9]:
Chart Context with Mesh and Axis0.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0

In addition to that, we can put label text to the axis.

In [10]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,480),|root|{// The following code will create a chart contextletmutchart=ChartBuilder::on(&root).caption("Chart with Axis Label",("Arial",20).into_font()).x_label_area_size(40).y_label_area_size(40).build_cartesian_2d(0f32..1f32,0f32..1f32)?;chart.configure_mesh().x_desc("Here's the label for X").y_desc("Here's the label for Y").draw()?;Ok(())}).style("width: 60%")
Out[10]:
Chart with Axis LabelHere's the label for YHere's the label for X0.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0

Then let's disable mesh lines for the X axis

In [12]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,480),|root|{// The following code will create a chart contextletmutchart=ChartBuilder::on(&root).caption("Chart Context with Mesh and Axis",("Arial",20).into_font()).x_label_area_size(40).y_label_area_size(40).build_cartesian_2d(0f32..1f32,0f32..1f32)?;chart.configure_mesh().y_labels(10).light_line_style(&TRANSPARENT).disable_x_mesh().draw()?;Ok(())}).style("width: 60%")
Out[12]:
Chart Context with Mesh and Axis0.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0

To create multiple charts in a single figure, you can just split the drawing area and create multiple chart context.

In [13]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,480),|root|{letsub_areas=root.split_evenly((2,2));for(idx,area)in(1..).zip(sub_areas.iter()){// The following code will create a chart contextletmutchart=ChartBuilder::on(&area).caption(format!("Subchart #{}",idx),("Arial",15).into_font()).x_label_area_size(40).y_label_area_size(40).build_cartesian_2d(0f32..1f32,0f32..1f32)?;chart.configure_mesh().y_labels(10).light_line_style(&TRANSPARENT).disable_x_mesh().draw()?;}Ok(())}).style("width: 60%")
Out[13]:
Subchart #10.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0Subchart #20.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0Subchart #30.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0Subchart #40.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0

Series

Unlike most of the plotting libraries,Plotters doesn't actually define any types of chart. All the chart is abstracted to a concept of series. By doing so, you can put a histgoram series and a line plot series into the same chart context.The series is actually defined as an iterator of elements, just this.

This givesPlotters a huge flexibility on drawing charts. You can implement you own types of series and uses the coordinate translation and chart elements.

There are few types of predefined series, just for convenience:

  • Line Series
  • Histogram
  • Point Series

Scatter Plot

First of all, let's generate some random numbers.

In [14]:
:deprand={version="0.6.5"}externcraterand;userand::distributions::Normal;userand::distributions::Distribution;userand::thread_rng;letsd=0.13;letrandom_points:Vec<(f64,f64)>={letmutnorm_dist=Normal::new(0.5,sd);let(mutx_rand,muty_rand)=(thread_rng(),thread_rng());letx_iter=norm_dist.sample_iter(&mutx_rand);lety_iter=norm_dist.sample_iter(&muty_rand);x_iter.zip(y_iter).take(1000).collect()};random_points.len()
Out[14]:
1000

It's trivial to draw a scatter plot withPlotters. The only need is, provide a iterator of the elements as series.The following example shows how to make a 2D normal distribution figure. The red rectangle is the two sigma area and the red cross is the mean.

In [15]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,480),|root|{// The following code will create a chart contextletmutchart=ChartBuilder::on(&root).caption("Normal Distribution",("Arial",20).into_font()).x_label_area_size(40).y_label_area_size(40).build_ranged(0f64..1f64,0f64..1f64)?;chart.configure_mesh().disable_x_mesh().disable_y_mesh().draw()?;chart.draw_series(random_points.iter().map(|(x,y)|Circle::new((*x,*y),3,GREEN.filled())));// You can alawys freely draw on the drawing backendletarea=chart.plotting_area();lettwo_sigma=sd*2.0;area.draw(&Rectangle::new([(0.5-two_sigma,0.5-two_sigma),(0.5+two_sigma,0.5+two_sigma)],RED.mix(0.3).filled()))?;area.draw(&Cross::new((0.5,0.5),5,&RED))?;Ok(())}).style("width:60%")
Out[15]:
Normal Distribution0.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0

Histogram

We can also have histograms. For histograms, we can use the predefined histogram series struct to build the histogram easily. The following code demonstrate how to create both histogram for X and Y value ofrandom_points.

In [18]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series","all_elements"]}externcrateplotters;useplotters::prelude::*;evcxr_figure((640,480),|root|{letareas=root.split_evenly((2,1));letmutcharts=vec![];// The following code will create a chart contextfor(area,name)inareas.iter().zip(["X","Y"].into_iter()){letmutchart=ChartBuilder::on(&area).caption(format!("Histogram for {}",name),("Arial",20).into_font()).x_label_area_size(40).y_label_area_size(40).build_cartesian_2d(0u32..100u32,0f64..0.5f64)?;chart.configure_mesh().disable_x_mesh().disable_y_mesh().y_labels(5).x_label_formatter(&|x|format!("{:.1}",*xasf64/100.0)).y_label_formatter(&|y|format!("{}%",(*y*100.0)asu32)).draw()?;charts.push(chart);}lethist_x=Histogram::vertical(&charts[0]).style(RED.filled()).margin(0).data(random_points.iter().map(|(x,_)|((x*100.0)asu32,0.01)));lethist_y=Histogram::vertical(&charts[0]).style(GREEN.filled()).margin(0).data(random_points.iter().map(|(_,y)|((y*100.0)asu32,0.01)));charts[0].draw_series(hist_x);charts[1].draw_series(hist_y);Ok(())}).style("width:60%")
Out[18]:
Histogram for X10%20%30%40%0.00.10.20.30.40.50.60.70.80.91.0Histogram for Y10%20%30%40%0.00.10.20.30.40.50.60.70.80.91.0

Combination of Histogram and Scatter

In [26]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series","all_elements"]}useplotters::prelude::*;evcxr_figure((640,480),|root|{letroot=root.titled("Scatter with Histogram Example",("Arial",20).into_font())?;letareas=root.split_by_breakpoints([560],[80]);letmutx_hist_ctx=ChartBuilder::on(&areas[0]).y_label_area_size(40).build_cartesian_2d(0u32..100u32,0f64..0.5f64)?;letmuty_hist_ctx=ChartBuilder::on(&areas[3]).x_label_area_size(40).build_cartesian_2d(0f64..0.5f64,0..100u32)?;letmutscatter_ctx=ChartBuilder::on(&areas[2]).x_label_area_size(40).y_label_area_size(40).build_cartesian_2d(0f64..1f64,0f64..1f64)?;scatter_ctx.configure_mesh().disable_x_mesh().disable_y_mesh().draw()?;scatter_ctx.draw_series(random_points.iter().map(|(x,y)|Circle::new((*x,*y),3,GREEN.filled())))?;letx_hist=Histogram::vertical(&x_hist_ctx).style(RED.filled()).margin(0).data(random_points.iter().map(|(x,_)|((x*100.0)asu32,0.01)));lety_hist=Histogram::horizontal(&y_hist_ctx).style(GREEN.filled()).margin(0).data(random_points.iter().map(|(_,y)|((y*100.0)asu32,0.01)));x_hist_ctx.draw_series(x_hist)?;y_hist_ctx.draw_series(y_hist)?;Ok(())}).style("width:60%")
Out[26]:
Scatter with Histogram Example0.10.20.30.40.50.60.70.80.90.10.20.30.40.50.60.70.80.91.0

3D Plots

Plotters also support 3D plotting since 0.3. To plotting a 3D chart, it's quite simple: when constructing theChartContext, instead ofbuild_cartesian_2d, usebuild_cartesian_3d instead. Then you should get a plotting environment that supports accepts 3-dimensional coordinates.

In [41]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series","all_elements"]}useplotters::prelude::*;evcxr_figure((640,480),|root|{letroot=root.titled("3D Plotting",("Arial",20).into_font())?;letmutchart=ChartBuilder::on(&root).build_cartesian_3d(-10.0..10.0,-10.0..10.0,-10.0..10.0)?;// Draw a red circle parallel to XOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(8.0*a.cos(),0.0,8.0*a.sin())),&RED,))?;// Draw a green circle parallel to YOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(0.0,8.0*a.cos(),8.0*a.sin())),&GREEN,))?;Ok(())})
Out[41]:
3D Plotting

Draw Plot Components

Just like the 2D plots, we are able to draw the axis and axis panel easily. Unlike the 2D plots, 3D plots use the functionconfigure_axes to configure the chart components.

In [42]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series","all_elements"]}useplotters::prelude::*;evcxr_figure((640,480),|root|{letroot=root.titled("3D Plotting",("Arial",20).into_font())?;letmutchart=ChartBuilder::on(&root).build_cartesian_3d(-10.0..10.0,-10.0..10.0,-10.0..10.0)?;chart.configure_axes().draw()?;// Draw a red circle parallel to XOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(8.0*a.cos(),0.0,8.0*a.sin())),&RED,))?;// Draw a green circle parallel to YOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(0.0,8.0*a.cos(),8.0*a.sin())),&GREEN,))?;Ok(())})
Out[42]:
3D Plotting-8.0-6.0-4.0-2.00.02.04.06.08.010.0-8.0-6.0-4.0-2.00.02.04.06.08.010.0-8.0-6.0-4.0-2.00.02.04.06.08.010.0

Adjusting the 3D View

Unlike the 2D plot, 3D plot allows you to change the point of view. For example, rotate the plot or scale the plot, etc. This is done by the projection matrix, Plotters allows you override the default projection matrix, so that you can customize your view point of the 3D Plot. The following example shows how to look at the plot from top to bottom in the plot we have previously created.

In [47]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series","all_elements"]}useplotters::prelude::*;evcxr_figure((640,480),|root|{letroot=root.titled("3D Plotting",("Arial",20).into_font())?;letmutchart=ChartBuilder::on(&root).build_cartesian_3d(-10.0..10.0,-10.0..10.0,-10.0..10.0)?;chart.with_projection(|mutp|{p.pitch=1.5707;// 90 degreen pitch, thus we are looking the plot from topp.yaw=0.0;// Make plot's X axis parallel to screen's X axisp.into_matrix()// build the projection matrix});chart.configure_axes().draw()?;// Draw a red circle parallel to XOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(8.0*a.cos(),0.0,8.0*a.sin())),&RED,))?;// Draw a green circle parallel to YOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(0.0,8.0*a.cos(),8.0*a.sin())),&GREEN,))?;Ok(())})
Out[47]:
3D Plotting-8.0-6.0-4.0-2.00.02.04.06.08.010.0-8.0-6.0-4.0-2.00.02.04.06.08.010.0-8.0-6.0-4.0-2.00.02.04.06.08.010.0
In [48]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series","all_elements"]}useplotters::prelude::*;evcxr_figure((640,480),|root|{letroot=root.titled("3D Plotting",("Arial",20).into_font())?;letmutchart=ChartBuilder::on(&root).build_cartesian_3d(-10.0..10.0,-10.0..10.0,-10.0..10.0)?;chart.with_projection(|mutp|{p.pitch=0.7;p.yaw=0.7;p.scale=0.5;p.into_matrix()// build the projection matrix});chart.configure_axes().draw()?;// Draw a red circle parallel to XOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(8.0*a.cos(),0.0,8.0*a.sin())),&RED,))?;// Draw a green circle parallel to YOZ panelchart.draw_series(LineSeries::new((-314..314).map(|a|aasf64/100.0).map(|a|(0.0,8.0*a.cos(),8.0*a.sin())),&GREEN,))?;Ok(())})
Out[48]:
3D Plotting-8.0-6.0-4.0-2.00.02.04.06.08.010.0-8.0-6.0-4.0-2.00.02.04.06.08.010.0-8.0-6.0-4.0-2.00.02.04.06.08.010.0

A 2D Guassian Distribution Example

In [124]:
:depplotters={version="^0.3.0",default_features=false,features=["evcxr","all_series","all_elements"]}useplotters::prelude::*;fnpdf(x:f64,y:f64)->f64{constSDX:f64=0.1;constSDY:f64=0.1;constA:f64=5.0;letx=xasf64/10.0;lety=yasf64/10.0;A*(-x*x/2.0/SDX/SDX-y*y/2.0/SDY/SDY).exp()}evcxr_figure((640*2,480),|root|{letroot=root.titled("2D Guassian PDF",("Arial",20).into_font())?;let(left,right)=root.split_horizontally(640);for(pitch,yaw,area)invec![(0.6,0.3,left),(1.5707,0.0,right)]{letmutchart=ChartBuilder::on(&area).build_cartesian_3d(-3.0..3.0,0.0..6.0,-3.0..3.0)?;chart.with_projection(|mutp|{p.pitch=pitch;p.yaw=yaw;p.scale=0.7;p.into_matrix()// build the projection matrix});chart.configure_axes().draw()?;letseries=(-15..15).map(|x|std::iter::repeat(x).zip(-15..15)).flatten().map(|(x,z)|{letx=xasf64/5.0;letz=zasf64/5.0;Polygon::new(vec![(x,pdf(x,z),z),(x+0.2,pdf(x+0.2,z),z),(x+0.2,pdf(x+0.2,z+0.2),z+0.2),(x,pdf(x,z+0.2),z+0.2),],&HSLColor(240.0/360.0-240.0/360.0*pdf(x,z)/5.0,1.0,0.7))});chart.draw_series(series);}Ok(())})
Out[124]:
2D Guassian PDF-2.0-1.00.01.02.03.01.02.03.04.05.06.0-2.0-1.00.01.02.03.0-2.0-1.00.01.02.03.01.02.03.04.05.06.0-2.0-1.00.01.02.03.0

[8]ページ先頭

©2009-2025 Movatter.jp