Skip to content

Commit

Permalink
Merge pull request #27 from DJDuque/error
Browse files Browse the repository at this point in the history
Improve error handling with the `thiserror` crate.
Simplify API to compile and visualize plots when the `tectonic` feature is not enabled.
  • Loading branch information
DJDuque authored Jan 5, 2023
2 parents 528d393 + ae32ddd commit b8e734b
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 294 deletions.
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pgfplots"
version = "0.4.1" # Remember to also change this in the README.md
version = "0.5.0" # Remember to also change this in the README.md
edition = "2021"
license = "MIT"
description = "A Rust library to generate publication-quality figures"
Expand All @@ -9,14 +9,14 @@ repository = "https://github.com/DJDuque/pgfplots"
keywords = ["pgfplots", "plotting", "plot", "visualization", "latex"]
categories = ["visualization"]
documentation = "https://docs.rs/pgfplots"
exclude = ["examples/*.png"]

[dependencies]
opener = "0.5"
rand = "0.8"
tectonic = { version = "0.12", optional = true }
tempfile = { version = "3", optional = true }
opener = { version = "0.5", optional = true }

[features]
inclusive = ["dep:tectonic", "dep:tempfile", "dep:opener"]
tempfile = "3"
thiserror = "1"

[package.metadata.docs.rs]
all-features = true
Expand Down
48 changes: 4 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ Add the following to your `Cargo.toml` file:

```toml
[dependencies]
pgfplots = { version = "0.4", features = ["inclusive"] }
pgfplots = "0.5"
```

Plotting a quadratic function is as simple as:

```rust
use pgfplots::axis::plot::Plot2D;
use pgfplots::{axis::plot::Plot2D, Engine, Picture};

let mut plot = Plot2D::new();
plot.coordinates = (-100..100)
.into_iter()
.map(|i| (f64::from(i), f64::from(i*i)).into())
.collect();

plot.show()?;
Picture::from(plot).show_pdf(Engine::PdfLatex)?;
```

## [Examples](https://github.com/DJDuque/pgfplots/tree/main/examples)
Expand All @@ -42,47 +42,7 @@ A more extensive list of examples and their source code is available in the

## Features

- Inclusive: Allow users to process the LaTeX code that generates figures
- Tectonic: Allow users to process the LaTeX code that generates figures
without relying on any externally installed software, configuration, or
resource files. This is achieved by including the
[tectonic](https://crates.io/crates/tectonic) crate as a dependency.

If you already have a LaTeX distribution installed in your system, it is
recommended to process the LaTeX code directly. The `tectonic` crate pulls in a
lot of dependencies, which significantly increase compilation and processing
times. Plotting a quadratic function is still very simple:

```rust
use pgfplots::axis::plot::Plot2D;
use std::process::{Command, Stdio};

let mut plot = Plot2D::new();
plot.coordinates = (-100..100)
.into_iter()
.map(|i| (f64::from(i), f64::from(i*i)).into())
.collect();

let argument = plot.standalone_string().replace('\n', "").replace('\t', "");
Command::new("pdflatex")
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("-interaction=batchmode")
.arg("-halt-on-error")
.arg("-jobname=figure")
.arg(argument)
.status()
.expect("Error: unable to run pdflatex");
```

## Want to contribute?

There are multiple ways to contribute:
- Install and test PGFPlots. If it doesn't work as expected please [open an
issue](https://github.com/DJDuque/pgfplots/issues/new).
- Comment/propose a fix on some of the current [open
issues](https://github.com/DJDuque/pgfplots/issues).
- Read through the [documentation](https://docs.rs/pgfplots). If there is
something confusing, or you have a suggestion for something that could be
improved, please let the maintainer(s) know.
- Help evaluate [open pull requests](https://github.com/DJDuque/pgfplots/pulls),
by testing locally and reviewing what is proposed.
12 changes: 7 additions & 5 deletions examples/fitted_line.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use pgfplots::axis::{
plot::{ErrorCharacter, ErrorDirection, Plot2D, PlotKey, Type2D},
Axis, AxisKey,
use pgfplots::{
axis::{plot::*, *},
Engine, Picture,
};
use std::f64::consts::PI;

Expand Down Expand Up @@ -47,6 +47,8 @@ fn main() {
axis.add_key(AxisKey::Custom(String::from("legend entries={fit,data}")));
axis.add_key(AxisKey::Custom(String::from("legend pos=north west")));

#[cfg(feature = "inclusive")]
axis.show().unwrap();
#[cfg(feature = "tectonic")]
Picture::from(axis).show_pdf(Engine::Tectonic).unwrap();
#[cfg(not(feature = "tectonic"))]
Picture::from(axis).show_pdf(Engine::PdfLatex).unwrap();
}
16 changes: 10 additions & 6 deletions examples/rectangle_integration.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use pgfplots::axis::{
plot::{Plot2D, PlotKey, Type2D},
Axis, AxisKey,
use pgfplots::{
axis::{plot::*, *},
Engine, Picture,
};

fn main() {
Expand All @@ -18,14 +18,16 @@ fn main() {
.step_by(10)
.map(|i| (f64::from(i), f64::from(i * i)).into())
.collect();
// Currently have to "guess" the bar width. Still pending the \compat key
// Currently have to "guess" the bar width in pt units
// Still pending the \compat key
rectangles.add_key(PlotKey::Type2D(Type2D::YBar {
bar_width: 19.5,
bar_shift: 0.0,
}));
rectangles.add_key(PlotKey::Custom(String::from("fill=gray!20")));
rectangles.add_key(PlotKey::Custom(String::from("draw opacity=0.5")));

// Customise axis environment
let mut axis = Axis::new();
axis.set_title("Rectangle Integration");
axis.set_x_label("$x$");
Expand All @@ -36,6 +38,8 @@ fn main() {
axis.add_key(AxisKey::Custom(String::from("xlabel near ticks")));
axis.add_key(AxisKey::Custom(String::from("ylabel near ticks")));

#[cfg(feature = "inclusive")]
axis.show().unwrap();
#[cfg(feature = "tectonic")]
Picture::from(axis).show_pdf(Engine::Tectonic).unwrap();
#[cfg(not(feature = "tectonic"))]
Picture::from(axis).show_pdf(Engine::PdfLatex).unwrap();
}
17 changes: 10 additions & 7 deletions examples/snowflake.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use pgfplots::axis::{
plot::{Plot2D, PlotKey},
Axis, AxisKey,
use pgfplots::{
axis::{plot::*, *},
Engine, Picture,
};

fn main() {
Expand All @@ -17,17 +17,20 @@ fn main() {
};
vertices.push(vertices[0]);

// Set snowflake
let mut plot = Plot2D::new();
plot.coordinates = vertices.into_iter().map(|v| v.into()).collect();
plot.add_key(PlotKey::Custom(String::from("fill=gray!20")));

let mut axis = Axis::new();
// Customise axis environment
let mut axis = Axis::from(plot);
axis.set_title("Kloch Snowflake");
axis.plots.push(plot);
axis.add_key(AxisKey::Custom(String::from("hide axis")));

#[cfg(feature = "inclusive")]
axis.show().unwrap();
#[cfg(feature = "tectonic")]
Picture::from(axis).show_pdf(Engine::Tectonic).unwrap();
#[cfg(not(feature = "tectonic"))]
Picture::from(axis).show_pdf(Engine::PdfLatex).unwrap();
}

// Stolen from plotters crate example
Expand Down
77 changes: 20 additions & 57 deletions src/axis.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::{axis::plot::Plot2D, Picture};
use crate::axis::plot::Plot2D;
use std::fmt;

#[cfg(feature = "inclusive")]
use crate::ShowPdfError;
// Only imported for documentation. If you notice that this is no longer the
// case, please change it.
#[allow(unused_imports)]
use crate::Picture;

/// Plot inside an [`Axis`] environment.
pub mod plot;
Expand Down Expand Up @@ -56,15 +58,18 @@ impl fmt::Display for AxisKey {
/// # Examples
///
/// ```no_run
/// use pgfplots::axis::Axis;
/// # use pgfplots::ShowPdfError;
/// # fn main() -> Result<(), ShowPdfError> {
/// use pgfplots::{axis::Axis, Engine, Picture};
///
/// let mut axis = Axis::new();
/// axis.set_title("Picture of $\\gamma$ rays");
/// axis.set_x_label("$x$~[m]");
/// axis.set_y_label("$y$~[m]");
///
/// # #[cfg(feature = "inclusive")]
/// axis.show();
/// Picture::from(axis).show_pdf(Engine::PdfLatex)?;
/// # Ok(())
/// # }
/// ```
#[derive(Clone, Debug, Default)]
pub struct Axis {
Expand Down Expand Up @@ -96,6 +101,14 @@ impl fmt::Display for Axis {
}
}

impl From<Plot2D> for Axis {
fn from(plot: Plot2D) -> Self {
Axis {
keys: Vec::new(),
plots: vec![plot],
}
}
}
impl Axis {
/// Creates a new, empty axis environment.
///
Expand All @@ -104,7 +117,7 @@ impl Axis {
/// ```
/// use pgfplots::axis::Axis;
///
/// let mut axis = Axis::new();
/// let axis = Axis::new();
/// ```
pub fn new() -> Self {
Default::default()
Expand Down Expand Up @@ -175,56 +188,6 @@ impl Axis {
}
self.keys.push(key);
}
/// Return a [`String`] with valid LaTeX code that generates a standalone
/// PDF with the axis in a default picture environment.
///
/// # Note
///
/// Passing this string directly to e.g. `pdflatex` will fail to generate a
/// PDF document. It is usually necessary to [`str::replace`] all the
/// occurrences of `\n` and `\t` with white space before sending this string
/// as an argument to a LaTeX compiler.
///
/// # Examples
///
/// ```
/// use pgfplots::axis::Axis;
///
/// let mut axis = Axis::new();
/// assert_eq!(
/// r#"\documentclass{standalone}
/// \usepackage{pgfplots}
/// \begin{document}
/// \begin{tikzpicture}
/// \begin{axis}
/// \end{axis}
/// \end{tikzpicture}
/// \end{document}"#,
/// axis.standalone_string());
/// ```
pub fn standalone_string(&self) -> String {
let mut picture = Picture::new();
picture.axes.push(self.clone());
picture.standalone_string()
}
/// Show the axis in a default [`Picture`] as a standalone PDF. This will
/// create a file in the location returned by [`std::env::temp_dir()`] and
/// open it with the default PDF viewer in your system.
///
/// # Examples
///
/// ```no_run
/// use pgfplots::axis::Axis;
///
/// let mut axis = Axis::new();
/// axis.show();
/// ```
#[cfg(feature = "inclusive")]
pub fn show(&self) -> Result<(), ShowPdfError> {
let mut picture = Picture::new();
picture.axes.push(self.clone());
picture.show()
}
}

/// Control the scaling of an axis.
Expand Down
Loading

0 comments on commit b8e734b

Please sign in to comment.