• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Plotters - A Rust drawing library focus on data plotting for both WASM and native applications  ������
2
3<a href="https://crates.io/crates/plotters">
4    <img style="display: inline!important" src="https://img.shields.io/crates/v/plotters.svg"></img>
5</a>
6<a href="https://docs.rs/plotters">
7    <img style="display: inline!important" src="https://docs.rs/plotters/badge.svg"></img>
8</a>
9<a href="https://plotters-rs.github.io/rustdoc/plotters/">
10	<img style="display: inline! important" src="https://img.shields.io/badge/docs-development-lightgrey.svg"></img>
11</a>
12<a href="https://travis-ci.org/38/plotters">
13	<img style="display: inline! important" src="https://travis-ci.org/38/plotters.svg?branch=master"></img>
14</a>
15<a href="https://codecov.io/gh/38/plotters">
16    <img style="display: inline! important" src="https://codecov.io/gh/38/plotters/branch/master/graph/badge.svg" />
17</a>
18
19Plotters is drawing library designed for rendering figures, plots, and charts, in pure rust. Plotters supports various types of back-ends,
20including bitmap, vector graph, piston window, GTK/Cairo and WebAssembly.
21
22- A new Plotters Developer's Guide is working in progress. The preview version is available at [here](https://plotters-rs.github.io/book).
23- To try Plotters with interactive Jupyter notebook, or view [here](https://plotters-rs.github.io/plotters-doc-data/evcxr-jupyter-integration.html) for the static HTML version.
24- To view the WASM example, go to this [link](https://plumberserver.com/plotters-wasm-demo/index.html)
25- Currently we have all the internal code ready for console plotting, but a console based backend is still not ready. See [this example](https://github.com/38/plotters/blob/master/examples/console.rs) for how to plotting on Console with a customized backend.
26- Plotters now moved all backend code to sperate repository, check [FAQ list](#faq-list) for details
27
28## Gallery
29
30To view the source code for each example, please click on the example image.
31
32<a href="https://github.com/38/plotters/blob/master/examples/chart.rs">
33    <img src="https://plotters-rs.github.io/plotters-doc-data/sample.png" class="galleryItem" width=200px></img>
34</a>
35
36<a href="https://github.com/38/plotters/blob/master/examples/stock.rs">
37    <img src="https://plotters-rs.github.io/plotters-doc-data/stock.png" class="galleryItem" width=200px></img>
38</a>
39
40<a href="https://github.com/38/plotters/blob/master/examples/histogram.rs">
41    <img src="https://plotters-rs.github.io/plotters-doc-data/histogram.png" class="galleryItem" width=200px></img>
42</a>
43
44<a href="https://github.com/38/plotters#quick-start">
45    <img src="https://plotters-rs.github.io/plotters-doc-data/0.png" class="galleryItem" width=200px></img>
46</a>
47
48<a href="#">
49	<img src="https://plotters-rs.github.io/plotters-doc-data/console-2.png" class="galleryItem" width=200px></img>
50</a>
51
52<a href="https://github.com/38/plotters/blob/master/examples/mandelbrot.rs">
53    <img src="https://plotters-rs.github.io/plotters-doc-data/mandelbrot.png" class="galleryItem" width=200px></img>
54</a>
55
56<a href="https://github.com/38/plotters#trying-with-jupyter-evcxr-kernel-interactively">
57    <img src="https://plotters-rs.github.io/plotters-doc-data/evcxr_animation.gif" class="galleryItem" width=200px></img>
58</a>
59
60
61<a href="https://github.com/plotters-rs/plotters-piston/blob/master/examples/cpustat.rs">
62    <img src="https://plotters-rs.github.io/plotters-doc-data/plotters-piston.gif" class="galleryItem" width=200px></img>
63</a>
64
65<a href="https://github.com/38/plotters/blob/master/examples/normal-dist.rs">
66    <img src="https://plotters-rs.github.io/plotters-doc-data/normal-dist.png" class="galleryItem" width=200px></img>
67</a>
68
69<a href="https://github.com/38/plotters/blob/master/examples/two-scales.rs">
70    <img src="https://plotters-rs.github.io/plotters-doc-data/twoscale.png" class="galleryItem" width=200px></img>
71</a>
72
73<a href="https://github.com/38/plotters/blob/master/examples/matshow.rs">
74    <img src="https://plotters-rs.github.io/plotters-doc-data/matshow.png" class="galleryItem" width=200px></img>
75</a>
76
77<a href="https://github.com/38/plotters/blob/master/examples/sierpinski.rs">
78	<img src="https://plotters-rs.github.io/plotters-doc-data/sierpinski.png" class="galleryItem" width=200px></img>
79</a>
80
81<a href="https://github.com/38/plotters/blob/master/examples/normal-dist2.rs">
82	<img src="https://plotters-rs.github.io/plotters-doc-data/normal-dist2.png" class="galleryItem" width=200px></img>
83</a>
84
85<a href="https://github.com/38/plotters/blob/master/examples/errorbar.rs">
86	<img src="https://plotters-rs.github.io/plotters-doc-data/errorbar.png" class="galleryItem" width=200px></img>
87</a>
88
89<a href="https://github.com/38/plotters/blob/master/examples/slc-temp.rs">
90	<img src="https://plotters-rs.github.io/plotters-doc-data/slc-temp.png" class="galleryItem" width=200px></img>
91</a>
92
93<a href="https://github.com/38/plotters/blob/master/examples/area-chart.rs">
94	<img src="https://plotters-rs.github.io/plotters-doc-data/area-chart.png" class="galleryItem" width=200px></img>
95</a>
96
97<a href="https://github.com/38/plotters/blob/master/examples/snowflake.rs">
98	<img src="https://plotters-rs.github.io/plotters-doc-data/snowflake.png" class="galleryItem" width=200px></img>
99</a>
100
101<a href="https://github.com/38/plotters/blob/master/examples/animation.rs">
102	<img src="https://plotters-rs.github.io/plotters-doc-data/animation.gif" class="galleryItem" width=200px></img>
103</a>
104
105<a href="https://github.com/38/plotters/blob/master/examples/console.rs">
106	<img src="https://plotters-rs.github.io/plotters-doc-data/console-example.png" class="galleryItem" width=200px></img>
107</a>
108
109<a href="https://github.com/38/plotters/blob/master/examples/console.rs">
110	<img src="https://plotters-rs.github.io/plotters-doc-data/console.png" class="galleryItem" width=200px></img>
111</a>
112
113<a href="https://github.com/38/plotters/blob/master/examples/blit-bitmap.rs">
114	<img src="https://plotters-rs.github.io/plotters-doc-data/blit-bitmap.png" class="galleryItem" width=200px></img>
115</a>
116
117<a href="https://github.com/38/plotters/blob/master/examples/boxplot.rs">
118	<img src="https://plotters-rs.github.io/plotters-doc-data/boxplot.svg" class="galleryItem" width=200px></img>
119</a>
120
121<a href="https://github.com/38/plotters/blob/master/examples/3d-plot.rs">
122	<img src="https://plotters-rs.github.io/plotters-doc-data/3d-plot.svg" class="galleryItem" width=200px></img>
123</a>
124
125<a href="https://github.com/38/plotters/blob/master/examples/3d-plot2.rs">
126	<img src="https://plotters-rs.github.io/plotters-doc-data/3d-plot2.gif" class="galleryItem" width=200px></img>
127</a>
128
129<a href="https://github.com/38/plotters/blob/master/examples/tick_control.rs">
130	<img src="https://plotters-rs.github.io/plotters-doc-data/tick_control.svg" class="galleryItem" width=200px></img>
131</a>
132
133
134## Table of Contents
135  * [Gallery](#gallery)
136  * [Quick Start](#quick-start)
137  * [Trying with Jupyter evcxr Kernel Interactively](#trying-with-jupyter-evcxr-kernel-interactively)
138  * [Interactive Tutorial with Jupyter Notebook](#interactive-tutorial-with-jupyter-notebook)
139  * [Plotting in Rust](#plotting-in-rust)
140  * [Plotting on HTML5 canvas with WASM Backend](#plotting-on-html5-canvas-with-wasm-backend)
141  * [What types of figure are supported?](#what-types-of-figure-are-supported)
142  * [Concepts by examples](#concepts-by-examples)
143    + [Drawing Back-ends](#drawing-back-ends)
144    + [Drawing Area](#drawing-area)
145    + [Elements](#elements)
146    + [Composable Elements](#composable-elements)
147    + [Chart Context](#chart-context)
148  * [Misc](#misc)
149    + [Development Version](#development-version)
150    + [Reducing Depending Libraries && Turning Off Backends](#reducing-depending-libraries--turning-off-backends)
151    + [List of Features](#list-of-features)
152  * [FAQ List](#faq-list)
153
154## Quick Start
155
156To use Plotters, you can simply add Plotters into your `Cargo.toml`
157```toml
158[dependencies]
159plotters = "^0.3.1"
160```
161
162And the following code draws a quadratic function. `src/main.rs`,
163
164```rust
165use plotters::prelude::*;
166fn main() -> Result<(), Box<dyn std::error::Error>> {
167    let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area();
168    root.fill(&WHITE)?;
169    let mut chart = ChartBuilder::on(&root)
170        .caption("y=x^2", ("sans-serif", 50).into_font())
171        .margin(5)
172        .x_label_area_size(30)
173        .y_label_area_size(30)
174        .build_cartesian_2d(-1f32..1f32, -0.1f32..1f32)?;
175
176    chart.configure_mesh().draw()?;
177
178    chart
179        .draw_series(LineSeries::new(
180            (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
181            &RED,
182        ))?
183        .label("y = x^2")
184        .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED));
185
186    chart
187        .configure_series_labels()
188        .background_style(&WHITE.mix(0.8))
189        .border_style(&BLACK)
190        .draw()?;
191
192    Ok(())
193}
194```
195
196![](https://plotters-rs.github.io/plotters-doc-data/0.png)
197
198
199## Trying with Jupyter evcxr Kernel Interactively
200
201Plotters now supports integrate with `evcxr` and is able to interactively drawing plots in Jupyter Notebook.
202The feature `evcxr` should be enabled when including Plotters to Jupyter Notebook.
203
204The following code shows a minimal example of this.
205
206```text
207:dep plotters = { git = "https://github.com/38/plotters", default_features = false, features = ["evcxr"] }
208extern crate plotters;
209use plotters::prelude::*;
210
211let figure = evcxr_figure((640, 480), |root| {
212    root.fill(&WHITE);
213    let mut chart = ChartBuilder::on(&root)
214        .caption("y=x^2", ("Arial", 50).into_font())
215        .margin(5)
216        .x_label_area_size(30)
217        .y_label_area_size(30)
218        .build_cartesian_2d(-1f32..1f32, -0.1f32..1f32)?;
219
220    chart.configure_mesh().draw()?;
221
222    chart.draw_series(LineSeries::new(
223        (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
224        &RED,
225    )).unwrap()
226        .label("y = x^2")
227        .legend(|(x,y)| PathElement::new(vec![(x,y), (x + 20,y)], &RED));
228
229    chart.configure_series_labels()
230        .background_style(&WHITE.mix(0.8))
231        .border_style(&BLACK)
232        .draw()?;
233    Ok(())
234});
235figure
236```
237
238<img src="https://plotters-rs.github.io/plotters-doc-data/evcxr_animation.gif" width="450px"></img>
239
240## Interactive Tutorial with Jupyter Notebook
241
242*This tutorial is now working in progress and isn't complete*
243
244Thanks to the evcxr, now we have an interactive tutorial for Plotters!
245To use the interactive notebook, you must have Jupyter and evcxr installed on your computer.
246Follow the instruction on [this page](https://github.com/google/evcxr/tree/master/evcxr_jupyter) below to install it.
247
248After that, you should be able to start your Jupyter server locally and load the tutorial!
249
250```bash
251git clone https://github.com/38/plotters-doc-data
252cd plotteres-doc-data
253jupyter notebook
254```
255
256And select the notebook called `evcxr-jupyter-integration.ipynb`.
257
258Also, there's a static HTML version of this notebook available at the [this location](https://plumberserver.com/plotters-docs/evcxr-jupyter-integration.html)
259
260## Plotting in Rust
261
262Rust is a perfect language for data visualization. Although there are many mature visualization libraries in many different languages.
263But Rust is one of the best languages fits the need.
264
265* **Easy to use** Rust has a very good iterator system built into the standard library. With the help of iterators,
266Plotting in Rust can be as easy as most of the high-level programming languages. The Rust based plotting library
267can be very easy to use.
268
269* **Fast** If you need rendering a figure with trillions of data points,
270Rust is a good choice. Rust's performance allows you to combine data processing step
271and rendering step into a single application. When plotting in high-level programming languages,
272e.g. Javascript or Python, data points must be down-sampled before feeding into the plotting
273program because of the performance considerations. Rust is fast enough to do the data processing and visualization
274within a single program. You can also integrate the
275figure rendering code into your application handling a huge amount of data and visualize it in real-time.
276
277* **WebAssembly Support** Rust is one of few the language with the best WASM support. Plotting in Rust could be
278very useful for visualization on a web page and would have a huge performance improvement comparing to Javascript.
279
280## Plotting on HTML5 canvas with WASM Backend
281
282Plotters currently supports backend that uses the HTML5 canvas. To use the WASM support, you can simply use
283`CanvasBackend` instead of other backend and all other API remains the same!
284
285There's a small demo for Plotters + WASM under `examples/wasm-demo` directory of this repo.
286To play with the deployed version, follow this [link](https://plumberserver.com/plotters-wasm-demo/index.html).
287
288
289## What types of figure are supported?
290
291Plotters is not limited to any specific type of figure.
292You can create your own types of figures easily with the Plotters API.
293
294But Plotters provides some builtin figure types for convenience.
295Currently, we support line series, point series, candlestick series, and histogram.
296And the library is designed to be able to render multiple figure into a single image.
297But Plotter is aimed to be a platform that is fully extendable to support any other types of figure.
298
299## Concepts by examples
300
301### Drawing Back-ends
302Plotters can use different drawing back-ends, including SVG, BitMap, and even real-time rendering. For example, a bitmap drawing backend.
303
304```rust
305use plotters::prelude::*;
306fn main() -> Result<(), Box<dyn std::error::Error>> {
307    // Create a 800*600 bitmap and start drawing
308    let mut backend = BitMapBackend::new("plotters-doc-data/1.png", (300, 200));
309    // And if we want SVG backend
310    // let backend = SVGBackend::new("output.svg", (800, 600));
311    backend.draw_rect((50, 50), (200, 150), &RED, true)?;
312    Ok(())
313}
314```
315
316![](https://plotters-rs.github.io/plotters-doc-data/1.png)
317
318### Drawing Area
319Plotters uses a concept called drawing area for layout purpose.
320Plotters support multiple integrating into a single image.
321This is done by creating sub-drawing-areas.
322
323Besides that, the drawing area also allows the customized coordinate system, by doing so, the coordinate mapping is done by the drawing area automatically.
324
325```rust
326use plotters::prelude::*;
327fn main() -> Result<(), Box<dyn std::error::Error>> {
328    let root_drawing_area =
329        BitMapBackend::new("plotters-doc-data/2.png", (300, 200)).into_drawing_area();
330    // And we can split the drawing area into 3x3 grid
331    let child_drawing_areas = root_drawing_area.split_evenly((3, 3));
332    // Then we fill the drawing area with different color
333    for (area, color) in child_drawing_areas.into_iter().zip(0..) {
334        area.fill(&Palette99::pick(color))?;
335    }
336    Ok(())
337}
338```
339
340![](https://plotters-rs.github.io/plotters-doc-data/2.png)
341
342### Elements
343
344In Plotters, elements are build blocks of figures. All elements are able to draw on a drawing area.
345There are different types of built-in elements, like lines, texts, circles, etc.
346You can also define your own element in the application code.
347
348You may also combine existing elements to build a complex element.
349
350To learn more about the element system, please read the [element module documentation](./element/index.html).
351
352```rust
353use plotters::prelude::*;
354fn main() -> Result<(), Box<dyn std::error::Error>> {
355    let root = BitMapBackend::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area();
356    root.fill(&WHITE)?;
357    // Draw an circle on the drawing area
358    root.draw(&Circle::new(
359        (100, 100),
360        50,
361        Into::<ShapeStyle>::into(&GREEN).filled(),
362    ))?;
363    Ok(())
364}
365```
366
367![](https://plotters-rs.github.io/plotters-doc-data/3.png)
368
369### Composable Elements
370
371Besides the built-in elements, elements can be composed into a logic group we called composed elements.
372When composing new elements, the upper-left corner is given in the target coordinate, and a new pixel-based
373coordinate which has the upper-left corner defined as `(0,0)` is used for further element composition purpose.
374
375For example, we can have an element which includes a dot and its coordinate.
376
377```rust
378use plotters::prelude::*;
379use plotters::coord::types::RangedCoordf32;
380
381fn main() -> Result<(), Box<dyn std::error::Error>> {
382    let root = BitMapBackend::new("plotters-doc-data/4.png", (640, 480)).into_drawing_area();
383
384    root.fill(&RGBColor(240, 200, 200))?;
385
386    let root = root.apply_coord_spec(Cartesian2d::<RangedCoordf32, RangedCoordf32>::new(
387        0f32..1f32,
388        0f32..1f32,
389        (0..640, 0..480),
390    ));
391
392    let dot_and_label = |x: f32, y: f32| {
393        return EmptyElement::at((x, y))
394            + Circle::new((0, 0), 3, ShapeStyle::from(&BLACK).filled())
395            + Text::new(
396                format!("({:.2},{:.2})", x, y),
397                (10, 0),
398                ("sans-serif", 15.0).into_font(),
399            );
400    };
401
402    root.draw(&dot_and_label(0.5, 0.6))?;
403    root.draw(&dot_and_label(0.25, 0.33))?;
404    root.draw(&dot_and_label(0.8, 0.8))?;
405    Ok(())
406}
407```
408
409![](https://plotters-rs.github.io/plotters-doc-data/4.png)
410
411### Chart Context
412
413In order to draw a chart, Plotters need a data object built on top of the drawing area called `ChartContext`.
414The chart context defines even higher level constructs compare to the drawing area.
415For example, you can define the label areas, meshes, and put a data series onto the drawing area with the help
416of the chart context object.
417
418```rust
419use plotters::prelude::*;
420fn main() -> Result<(), Box<dyn std::error::Error>> {
421    let root = BitMapBackend::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area();
422    root.fill(&WHITE);
423    let root = root.margin(10, 10, 10, 10);
424    // After this point, we should be able to draw construct a chart context
425    let mut chart = ChartBuilder::on(&root)
426        // Set the caption of the chart
427        .caption("This is our first plot", ("sans-serif", 40).into_font())
428        // Set the size of the label region
429        .x_label_area_size(20)
430        .y_label_area_size(40)
431        // Finally attach a coordinate on the drawing area and make a chart context
432        .build_cartesian_2d(0f32..10f32, 0f32..10f32)?;
433
434    // Then we can draw a mesh
435    chart
436        .configure_mesh()
437        // We can customize the maximum number of labels allowed for each axis
438        .x_labels(5)
439        .y_labels(5)
440        // We can also change the format of the label text
441        .y_label_formatter(&|x| format!("{:.3}", x))
442        .draw()?;
443
444    // And we can draw something in the drawing area
445    chart.draw_series(LineSeries::new(
446        vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
447        &RED,
448    ))?;
449    // Similarly, we can draw point series
450    chart.draw_series(PointSeries::of_element(
451        vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
452        5,
453        &RED,
454        &|c, s, st| {
455            return EmptyElement::at(c)    // We want to construct a composed element on-the-fly
456            + Circle::new((0,0),s,st.filled()) // At this point, the new pixel coordinate is established
457            + Text::new(format!("{:?}", c), (10, 0), ("sans-serif", 10).into_font());
458        },
459    ))?;
460    Ok(())
461}
462```
463
464![](https://plotters-rs.github.io/plotters-doc-data/5.png)
465
466## Misc
467
468### Development Version
469
470To use the latest development version, pull https://github.com/38/plotters.git. In `Cargo.toml`
471
472```toml
473[dependencies]
474plotters = { git = "https://github.com/38/plotters.git" }
475```
476
477### Reducing Depending Libraries && Turning Off Backends
478Plotters now supports use features to control the backend dependencies. By default, `BitMapBackend` and `SVGBackend` are supported,
479use `default_features = false` in the dependency description in `Cargo.toml` and you can cherry-pick the backend implementations.
480
481- `svg` Enable the `SVGBackend`
482- `bitmap` Enable the `BitMapBackend`
483
484For example, the following dependency description would avoid compiling with bitmap support:
485
486```toml
487[dependencies]
488plotters = { git = "https://github.com/38/plotters.git", default_features = false, features = ["svg"] }
489```
490
491The library also allows consumers to make use of the [`Palette`](https://crates.io/crates/palette/) crate's color types by default.
492This behavior can also be turned off by setting `default_features = false`.
493
494### List of Features
495
496This is the full list of features that is defined by `Plotters` crate.
497Use `default_features = false` to disable those default enabled features,
498and then you should be able to cherry-pick what features you want to include into `Plotters` crate.
499By doing so, you can minimize the number of dependencies down to only `itertools` and compile time is less than 6s.
500
501The following list is a complete list of features that can be opt in and out.
502
503- Tier 1 drawing backends
504
505| Name    |  Description | Additional Dependency |Default?|
506|---------|--------------|--------|------------|
507| bitmap\_encoder  | Allow `BitMapBackend` save the result to bitmap files | image, rusttype, font-kit | Yes |
508| svg\_backend     | Enable `SVGBackend` Support | None | Yes |
509| bitmap\_gif| Opt-in GIF animation Rendering support for `BitMapBackend`, implies `bitmap` enabled | gif | Yes |
510
511- Font manipulation features
512
513| Name    |  Description | Additional Dependency |Default?|
514|---------|--------------|--------|------------|
515| ttf | Allows TrueType font support | rusttype, font-kit | Yes |
516
517- Coordinate features
518
519| Name    |  Description | Additional Dependency |Default?|
520|---------|--------------|--------|------------|
521| datetime | Eanble the date and time coordinate support | chrono | Yes |
522
523- Element, series and util functions
524
525| Name    |  Description | Additional Dependency |Default?|
526|---------|--------------|--------|------------|
527| errorbar | The errorbar element support | None | Yes |
528| candlestick | The candlestick element support | None | Yes |
529| boxplot | The boxplot element support | None | Yes |
530| area\_series | The area series support | None | Yes |
531| line\_series | The line series support | None | Yes |
532| histogram | The histogram series support | None | Yes |
533| point\_series| The point series support | None | Yes |
534
535- Misc
536
537| Name    |  Description | Additional Dependency |Default?|
538|---------|--------------|--------|------------|
539| deprecated\_items | This feature allows use of deprecated items which is going to be removed in the future | None | Yes |
540| debug | Enable the code used for debugging | None | No |
541
542
543## FAQ List
544
545* Why does the WASM example break on my machine ?
546
547	The WASM example requires using `wasm32` target to build. Using `cargo build` is likely to use the default target
548	which in most of the case is any of the x86 target. Thus you need add `--target=wasm32-unknown-unknown` in the cargo
549	parameter list  to build it.
550
551* How to draw text/circle/point/rectangle/... on the top of chart ?
552
553	As you may realized, Plotters is a drawing library rather than a traditional data plotting library,
554	you have the freedom to draw anything you want on the drawing area.
555	Use `DrawingArea::draw` to draw any element on the drawing area.
556
557* Where can I find the backend code ?
558
559	Since Plotters 0.3, all drawing backends are independent crate from the main Plotters crate.
560	Use the following link to find the backend code:
561
562	- [Bitmap Backend](https://github.com/plotters-rs/plotters-bitmap.git)
563	- [SVG Backend](https://github.com/plotters-rs/plotters-svg.git)
564	- [HTML5 Canvas Backend](https://github.com/plotters-rs/plotters-canvas.git)
565	- [GTK/Cairo Backend](https://github.com/plotters-rs/plotters-cairo.git)
566
567
568