Giter Site home page Giter Site logo

rustgnuplot's Introduction

RustGnuplot

A Gnuplot controller written in Rust.

Build Status

Documentation

On docs.rs

Examples

A simple example:

let mut fg = Figure::new();
fg.axes2d()
	.set_title("A plot", &[])
	.set_legend(Graph(0.5), Graph(0.9), &[], &[])
	.set_x_label("x", &[])
	.set_y_label("y^2", &[])
	.lines(
		&[-3., -2., -1., 0., 1., 2., 3.],
		&[9., 4., 1., 0., 1., 4., 9.],
		&[Caption("Parabola")],
	);
fg.show().unwrap();

Simple example plot

A somewhat involved 2D example (see example1.rs in the examples directory):

Complicated example plot

Features

  • Simple 2D plots
    • lines
    • points
    • points + lines
    • error bars
    • ...and more!
  • Simple 3D plots
    • surface plots
    • heatmaps
    • contours

Building

Via Cargo

cargo build

rustgnuplot's People

Contributors

amelia10007 avatar artemgr avatar atouchet avatar cexen avatar chris00 avatar chrisjefferson avatar hwchen avatar justwalt avatar matt-thomson avatar neutroni avatar piotrfila avatar rekka avatar robeirne avatar semitom avatar siegelord avatar siegelordex avatar solarsail avatar steveklabnik avatar tazoeur avatar tomwhatmore avatar whmountains avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rustgnuplot's Issues

A way to set the canvas size?

Resizing the graph should be as simple as "set term pbm size 600, 400" if I'm reading the docs right. But I wasn't able to find something like that in the library. Is this a missing option?

Cannot move out of dereference of `&`-pointer

The code is broken with the latest rust nightly
rustc --version
rustc 0.13.0-nightly (193390d0e 2014-12-11 22:56:54 +0000)
cargo --version
cargo 0.0.1-pre-nightly (0f6667c 2014-12-08 21:19:01 +0000)

I get many errors like the one below when I compile my code which uses rust gnuplot

src/util.rs:11:10: 11:12 error: cannot move out of dereference of `&`-pointer
src/util.rs:11          match *o
                              ^~
src/util.rs:5:1: 22:2 note: in expansion of first_opt!
src/axes_common.rs:166:3: 177:3 note: expansion site
src/axes_common.rs:167:14: 167:15 note: attempting to move value to here
src/axes_common.rs:167          TextAlign(a) =>
                                          ^
src/util.rs:5:1: 22:2 note: in expansion of first_opt!
src/axes_common.rs:166:3: 177:3 note: expansion site
src/axes_common.rs:167:14: 167:15 help: to prevent the move, use `ref a` or `ref mut a` to capture value by reference

Per-datapoint styles

E.g. points with varying size/color etc.

The most logical way to do it would be how we did the boxes_with_size, but it'll get unwieldy without default/keyword args. Alternatively, Color and PointSize options could take iterators... unfortunately default type bounds don't work so we can't make that work ergonomically. I really don't want to go the route of criterion etc where plots are done off structs.

See http://gnuplot.sourceforge.net/demo/pointsize.html for the implementation details. We'll be using lc palette for colors.

How to create gif animation?

Hello, I'm trying to create gif animation by the code like following.
But only last frame was recorded in "movie.gif".
Is this the wrong usage of functions or the limitation of the current package?

let mut fg = Figure::new();
fg.set_terminal("gif animate optimize delay 2 size 480,360", "movie.gif");
for _ in 0..10 {
    fg.clear_axes();
    // calculate x, y
    fg.axes2d().lines_points(&x,&y);
    fg.show();
}

How to detect whether the gnuplot terminal is still running?

I want my rust code to loop {} until the plot window is closed. How do I do this?

This is needed, as most gnuplot terminals loose control facilities if the their gnuplot process dies, which always happens if the rust program which spawned gnuplot dies. So in order to have that rust program wait for the gnuplot terminal to terminate, one needs to know whether gnuplot is still running.

PDF output size in pixels

Is there any way to set the output PDF size in pixels, not inches. Or at least specify the size in inches, though support fractional sizes?

Show the zero axis

RustGnuplot is unable to display the zero axis on gnuplot. The gnuplot commands are set xzeroaxis and set yzeroaxis, given here.

Caption ownership troubles

Hi,
I'm quite new to rust, so I'm still struggling with lifetimes, ownerships et al.

I'd like to do this (stripped down to the essence):

use gnuplot::Figure;
pub fn make_figure<'a>(x: f64, y: f64) -> Figure<'a> {
    use gnuplot::Caption;
    let point_caption = format!("Point, x = {}, y = {}", x, y);
    let mut fg = Figure::new();
    let axes = fg.axes2d();
    axes.points(&[x], &[y], &[Caption(&point_caption)]);
    fg
}

However, point_caption is created locally so it is dropped on function return. axes.points passes it in Caption via reference, so it requires it to live at least as long as the figure being returned. Thus, given snippet does not compile.

What should I do here? Passing the caption in parameters to make_figure would be very annoying, is there a better way available?

The docs have gone?

Hi, your docs seem to 404 atm. Also, your badge says the build is failing but on my 2014-11-13 nightly it is building just fine...

Escaped strings prevent newlines

With 68f89f1 applied, it's no longer possible to use labels with embedded newlines.

Minimal example:

use gnuplot::{AxesCommon, Coordinate, Figure};

fn main() {
    let mut fg = Figure::new();
    let _ax = fg
        .axes2d()
        .label(r"multi\nline\nstring", Coordinate::Graph(0.), Coordinate::Graph(0.), &[]);

    let mut stdout = std::io::stdout();
    fg.echo(&mut stdout);
}

With gnuplot 0.0.34, the output includes:

set label 1 "multi\nline\nstring" at  graph 8.0000000000000004e-1, graph 9.0000000000000002e-1 front

And with gnuplot 0.0.36, the output includes:

set label 1 "multi\\nline\\nstring" at  graph 8.0000000000000004e-1, graph 9.0000000000000002e-1 front

I'm not sure what would be the best way to handle this. At first I considered that you could add some whitelisted sequences in util::escape() to permit \n and maybe others. But then that breaks if you use a path of C:\new plot, for example.

From the Gnuplot documention, part III, the "cd" command, it suggests using single-quotes for Windows paths. Maybe it would be better in this crate to be able support writing string literals with either double quotes or single quotes.

Not alternating colors when drawing lines

Not sure if I'm doing anything wrong but with this example both lines are drawn using the same color, making impossible to distinguish them. Using points() instead of lines() does alternate the color and pattern. Shouldn't lines() do it as well?

use gnuplot::*;

fn main() {
    let mut fg = Figure::new();

    fg.axes2d()
        .lines(&[1, 2, 3], &[1, 2, 3], &[Caption("fst")])
        .lines(&[1, 2, 3], &[4, 5, 6], &[Caption("snd")]);

    fg.show();
}

`set y2tics` command is supported?

Hi.

I want to set mutiple y axes in the left side(the first axis) and right size(the 2nd axis).
In the gnuplot document, I found that set y2tics is what I need.
So, does RustGnuplot support set y2tics gnuplot command? I couldn't find it in your library😢

It seems that a process of gnuplot_qt still runs after the program exits

I wrote a program that uses gnuplot to plot data. After the program terminates normally there will remain a running gnuplot_qt process.

The code of the minimum test program is

use gnuplot::{Figure};

fn main() {
    let mut fig=Figure::new();
    fig.axes2d().lines(&[1,2,3,4],&[1,2,3,4],&[]);
    fig.show().unwrap();
}

Before running the program, I run following commands to ensure that all previously running gnuplot have already been killed:

for i in `pgrep gnuplot`
do
    kill -9 $i
done
pgrep gnuplot

Then I run the program as

cargo run 

Then the gnuplot window appears and I close it manually.
Then the program exits normally.

I check the process by using

pgrep gnuplot

It shows that there is a running gnuplot_qt process.

I repeatly run my program and more gnuplot_qt will appear and keep running if I leave them alone.

The version of gnuplot crate I use is 0.0.37 and the gnuplot version in my system is gnuplot 5.2 patchlevel 8

Wait for gnuplot to create the output file before continuing

I want to create a plot using gnuplot and directly afterwards read the file and process it further. Something like:

let fpath = Path::new("/tmp/plot.png");
let mut fg = Figure::new();
// Plotting code
fg.set_terminal("pngcairo", fpath.to_string_lossy());
fg.show();

// Now read the file again
let res = fs::read(fpath).unwrap();

However, reading the file fails with "No such file or directory". Putting a sleep before the read "solves" the problem. As such, the problem seems to be, that show() returns, before the file is actually shown/created.

Is there a way to wait for the gnuplot process to finish creating the output file, before show() returns?
The only thing I can imagine right now, is spawning a new gnuplot process for each image and using the termination of the process as a signal that the output file was created.

typo in documentation (axes2d::set_legend)

/// * label_options - Array of LegendOption options

should be
/// * legend_options - Array of LegendOption options

since that's the name of the parameter in the method below

Request for further 3D formats

Any chance of adding point plotting to the 3D axes?

I'm loving the 2D stuff, but really want to show some 3D point-cloud data that would work well using points, or "with impulses"

readme example labelled wrong

It's not that important, but the red line in the second example of the readme file is off:
It is labelled (x-4)^2 + 5 while it should be labelled -(x-4)^2 +5.

Set tick format

In gnuplot I normally do set xtics format "%.0f%%" for showing percentages. I would love to have this feature in this crate!

Single iterator providing X-Y coordinates

Often, the X-Y coordinates come from a single iterator. Having to close that iterator and project on X and Y components is not very ergonomic.

Sadly, I do not see any way of improving that without breaking backward compatibility (one could define new methods but that would not be ergonomic either). My idea is to generalize plotting functions as

pub fn points(&'l mut self, xy: impl XY,
              options: &[PlotOption<&str>]) -> &'l mut Self

where the trait XY (or a longer name such as XYcoordinates) is implemented for

  • (X, Y) where X and Y are as before so older code simply has to add 2 parentheses,
  • IntoIterator<Item = &[(Tx, Ty)]
  • IntoIterator<Item = &[[T; 2]]

and maybe other types for which it makes sense.

What do you think?

Arguments describing filenames should be `&Path`/`PathBuf`

Arguments describing filenames, for example in the save_to_* functions should be of type &Path.

See example signature:

pub fn set_terminal<'l>(
  &'l mut self, terminal: &str,
  output_file: &Path   // <-- This becomes a Path
) -> &'l mut Figure

Errorbars on points without connecting lines?

Thanks for this nice library! I discovered that RustGnuplot uses gnuplot's errorlines in order to plot points with error bars. Is there a way to use errorbar instead? If i understand the documentation correctly, one could achieve the former by using errorbar + plot. On the other hand it seems like one cannot turn off the lines once they are plotted with errorlines. I also tried setting the linewidth to 0 to no avail. Am I missing something?

error happend `Gnuplot Version 5.4` on windows

Error message is

gnuplot> t output "mnd_density.png"
         ^
         line 0: invalid command

           line 0: warning: Couldn't slurp 8000000 bytes (return was 2194576)


multiplot> splot "-" binary endian=little array=(1000,1000) format="%float64" origin=(-5.000000000000e0,-5.000000000000e0,0) dx=1.001001001001e-2 dy=1.001001001001e-2  with pm3d t ""
                                                                                                                                                                                      ^
           line 0: All points x value undefined
 ���w>��53�'`�'IDATx��
0       �
@� �`�H0$`
0       �
@� �`�H0$`
0       �
@� �`�H0$`
0       �
@� �`�H0$`
0       �
<continue with similar charactors>

Please help me.

Date\Time axis support

Either with std::time or chrono please. The raw unix timestamps work but not handy in axis labeling.

reverse axis

Hi! Thanks for your work on this, it's been really helpful for plotting.

I'd like to reverse an axis. As far as I can tell, that is not currently a feature (but maybe I missed it?).

If you'd like, I can make a pull request for it.

animation_example.rs don't work

rustup 1.19.0 (2af131cf9 2019-09-08)
rustc 1.38.0 (625451e37 2019-09-23)

This is a silly example of doing an animation... Ctrl-C to quit.
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GnuplotInitError { inner: Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." } }', src\libcore\result.rs:1084:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: process didn't exit successfully: `D:\rust\RustGnuplot\target\debug\examples\animation_example.exe` (exit code: 101)

Possible bug in ARM.

I have a data collection daemon running on several Raspberry Pis which crash regularly (every few days) with the following error:

*** Error in `./sensorpi': free(): invalid pointer: 0x76b65f01 ***
./run.sh: line 3:     8 Aborted                 (core dumped) ./sensorpi

My crate doesn't have any unsafe code, so it must be an issue with the dependencies. I believe it is either in slice_deque or gnuplot. I am going to try replacing them one at a time and see if the error goes away. I will keep you updated and close this issue if it turns out to be a problem with another crate.

Problem when installing through cargo

I'm trying to use version 0.0.20 of rustgnuplot through Cargo, and when I try to cargo run the program through my Terminal I get this error:

thread '<main>' panicked at 'Couldn't spawn gnuplot. Make sure it is installed
                              and available in PATH.', ../src/libcore/option.rs:335

It builds fine with cargo build, but breaks when the program runs.

I saw issues #11 and #12 which deal with this exact problem, but I'm not quite sure what is meant by "make sure it is installed and available in PATH". My code in main.rs is just your example:

extern crate gnuplot;

use gnuplot::{Figure, Caption, Color};

fn main() {
    let x = [0u32, 1, 2];
    let y = [3u32, 4, 5];
    let mut fg = Figure::new();
    fg.axes2d()
    .lines(&x, &y, &[Caption("A line"), Color("black")]);
    fg.show();
}

Any idea what could be causing this error? I'm really new to Rust and Cargo, but I thought Cargo was supposed to handle all of this for me. Thanks in advance for your help!

Minor tics

RustGnuplot is unable to set or show minor tics. Minor tics on the x axis are controlled by set mxtics, from the docs.

fg.show() doesn't do anything

I have the following code:

// myexample.rs
let mut fg = Figure::new();
    
fg.set_terminal("qt", "");

fg.axes2d()
        .lines(&times, &lambda_values,
            &[
                Caption("λ(t)"),
                Color("#1E90FF"),
            ])
        .points(&event_times, &event_intens, 
            &[
                Caption("Events"),
                Color("black"),
                PointSymbol('O'),
                PointSize(0.8)])
        .set_x_label("Temps t", &[])
        .set_y_label("Intensité", &[]);
    
fg.show();

But when I run cargo run --example myexample, the gnuplot window doesn't show up (not even for a split second). When I choose a different backend such as pngcairo and an output file, it won't create the file either. I have to echo to a .gnuplot file and run gnuplot manually.

I'm running Windows 10 64-bit, with Rust 1.26.2 and gnuplot 5.3.

Error 'Invalid argument' when output path contains backslashes on Windows

On Windows it's common that paths contain backslashes (although forward slashes are also supported in many places). However, when I pass a path to a save_to_ function that contains backslashes, I get the following error:

gnuplot> set output "Z:\temp\out\energy\energy3d_test\plot.pdf"
                                                               ^
         line 0:          cannot open file; output not changed
system error: Invalid argument

Currently, I use the following workaround in my code

let output_file = output_path.join("plot.pdf");
if cfg!(windows) {
    // On Windows, gnuplot doesn't accept any backslashes in the path
    let output_file = output_file.to_str().unwrap().replace("\\", "/");
    fg.save_to_pdf(&output_file, 12, 8).unwrap();
} else {
    fg.save_to_pdf(&output_file, 12, 8).unwrap();
}

Either the backslashes have to be somehow escaped when passing them to the gnuplot executable or it doesn't support backslashes in the path at all. In any case, I think this should be handled by this library and not by user code. Unfortunately I don't have time at the moment to investigate this further.

grid

I miss a way to specify a grid for the 2D plots! This I feel is the most important feature missing in an otherwise awesome library.

mutating created axes

This is great.

However I ran into a problem where I have to call Axes2D.points() n times, where n is known only at runtime.

I can't figure out how to use the &mut returned by fg.axes2d() -- the figure seems to have permanent ownership. I notice all the examples construct the axes without binding them to a variable.

Is there a way to mutate existing axes in an existing figure?

Interactive gnuplot window

When using fg.show() a nice gnuplot window pops up and everything is good until I try to zoom or move around or in any way interact with the window. As far as I understand this is normal behavior when using the -p gnuplot parameter.

I think it would be better to use pause mouse close as the last command instead of -p. This command keeps the gnuplot process running until the window is closed and is probably better than -p since the window becomes interactive.

Currently I am using this workaround, but if you agree I think this would be a nice addition to the library.

let p = Command::new("gnuplot")
    .arg("/dev/stdin")
    .stdin(Stdio::piped())
    .spawn().unwrap();

let mut stdin = p.stdin.unwrap();
fig.echo(&mut stdin);
stdin.write_all(b"pause mouse close\n").unwrap();

multiplot

Does this library allow for multiplotting?

I tried to figure it out and well...I couldn't.

Support non-UTF8 filenames

The API uses Paths, but we convert to UTF8 before sending to gnuplot.

  • Need to investigate what gnuplot actually supports (probably it just passes it to C directly, but you never know)
  • Also handle paths with " in them, which isn't working right now either

Support polar plots

Would it be possible to support polar plots?

I think the key change is to be able to output set polar. Here are some examples.

Couldn't spawn gnuplot. Make sure it is installed and available in PATH

While running the example:

// This file is released into Public Domain.
use gnuplot::*;
use std::f32;

fn main()
{
	let mut fg = Figure::new();
	let mut x = vec![];
	for i in 0..100i32
	{
		x.push(i as f32 * 0.1 - 5.0);
	}

	let mut t = 0.0;
	fg.set_terminal("gif animate optimize delay 2 size 480,360", "fg.gif.gif");
	for i in 0..100
	{
		if i > 0
		{
			fg.new_page();
		}
		let ax = fg.axes2d().set_y_range(Fix(-1.0), Fix(1.0));
		ax.lines(
			x.iter(),
			x.iter()
				.map(|&x| (x + t as f32 * 0.1 * 2. * f32::consts::PI).sin()),
			&[Color("blue")],
		);
		ax.lines(
			x.iter(),
			x.iter()
				.map(|&x| (x + t as f32 * 0.1 * 2. * f32::consts::PI).cos()),
			&[Color("red")],
		);
		t += 0.1;
	}
	fg.echo_to_file("fg.gif.gnuplot");
	fg.show();
}

I got the error:

    Finished dev [unoptimized + debuginfo] target(s) in 0.20s
     Running `target\debug\rust.exe`
thread 'main' panicked at 'Couldn't spawn gnuplot. Make sure it is installed and available in PATH.: Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }', src\libcore\result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: process didn't exit successfully: `target\debug\rust.exe` (exit code: 101)

Knowing that I've gnuplot and it is installed in my Win 10 machine, and added to the path:

image

String labels for xtic

I was creating a bar chart using this library but found that it would not allow for strings to be attached to xtics. If this could be added it would be immensely useful for creating bar charts.

Latex support in labels.

Hello,

First, thank you for the crate. Very helpful.

I am trying to add symbols in the labels, like, nano, or $\lambda$ symbols.

Is this supported currently?

I tried doing this,

    let mut fg = Figure::new();
    fg.axes2d()
        .set_x_label("Normal contact displacement ($$\lambda$$ nano m)", &[])
        .set_y_label("Normal contact force (kN)", &[])
        .set_x_range(Fix(0.), Fix(400.))
        .set_y_range(Fix(0.), Fix(12.));

But it fails.

Doesn't pause when I write figure to file and pipe it to gnuplot

I want to store figure to a file and then pipe it to gnuplot to show the figure. figure.show() method works well. But when I pipe the file that I wrote to to gnuplot, it quit immediately. I tried to add a pause command in the end. However, it doesn't work.

Plot disappearing after replot

Hello,
I noticed that, when creating a Figure with two plots (2 rows, 1 colum), the first cell (index 0) seems to disappear during a replot.
It is sufficient to trigger a replot either with the proper button or by resizing the window and the plot in the first cell disappears.

I tried to plot with the same exact code both in cell 0 and cell 1, and I can reproduce the issue: cell 0 disappears on the first replot, while the second is properly replotted.

Is this only happening to me? Any idea what may be wrong?
Thanks!

Dash type works differently in gnuplot 5

Probably need to add some sort of gnuplot version specifier, since dash type works differently between 4 and 5. Could default to trying to determine it from gnuplot --version, falling back to 5. Also add a set_gnuplot_version to set it explicitly.

Fix the range of an axis

Hello,

First at all, thank you for your work on this library!

I have a question about fixing the range of an axis.

I tried:

let mut fg = Figure::new();
fg.axes2d().set_x_range(gnuplot::AutoOption::Fix(0.0), gnuplot::AutoOption::Fix(1.0));
fg.axes2d().lines_points(&times, &s1, &[Color("red"), PointSymbol('.')]);
fg.axes2d().lines_points(&times, &s2, &[Color("blue"), PointSymbol('.')]);

But it seems that it does not work (I got two different ranges for the x axis, which is not very beautiful...).

Any idea?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.