Changes for version 0.33 - 2026-10-30

  • New
    • `engine => 'gnuplot'` and `engine => 'ggplot2'` draw a figure with gnuplot 5.2 or newer, or with R and its package ggplot2 3.5.0 or newer, in place of matplotlib. Both draw `bar`, `barh`, `boxplot`, `colored_table`, `hist`, `hist2d`, `imshow`, `pie`, `plot`, `scatter`, `violin` and `wide`, alone, overlaid with `add`, or in a grid with `plots` or `p`, as `.svg`, `.png` or `.pdf`. The program to run is `gnuplot` or `Rscript`, or the path in `MATPLOTLIB_SIMPLE_GNUPLOT` or `MATPLOTLIB_SIMPLE_RSCRIPT`. `execute => 0` writes the script without running it, as before.
    • Whatever an engine does not draw is refused by name, with the types and keywords it does draw, rather than left out of the figure: `hexbin` and `venn_proportional_area`, Python of the caller's own such as `set_options` and `legend`, `tooltips`, `twinx`, `sharex` and `sharey`, `shared_colorbar`, `show`, and in gnuplot `edgecolor` on bars and `notch`. matplotlib, the default, draws everything it did.
    • gnuplot and ggplot2 read every keyword as matplotlib would. A color is one of matplotlib's names, drawn as matplotlib draws it, since gnuplot's and R's names differ from it and from each other; a `cmap` is one of 36 of matplotlib's colormaps, or one of them reversed with `_r`; a title holding Python of the caller's own, such as `'"Counts, by book"'`, is the words inside the quotes; and `set_xlim => '0, 10'` is the range. Text followed by matplotlib's own arguments, such as `fontsize = 20`, is refused.
    • `style` matches the engine by default: `style => 'native'` lets gnuplot or ggplot2 draw a figure in its own way, with its own palette and default colormap, its own boxplot quartiles, histogram bins and violin densities, and its own theme. With `style => 'matplotlib'` each draws what matplotlib draws -- the same colors, the same bins, quartiles and densities, computed as numpy and scipy compute them -- so that changing `engine` changes the renderer and not the figure. Under either style the data, key order, given colors and colormaps, labels, ranges, log scales and size are the caller's. Under matplotlib both styles draw the same figure.
    • An SVG drawn by gnuplot or ggplot2 carries the same note about where it came from as one drawn by matplotlib, in `<dc:creator><cc:Agent><dc:title>`, ending with the engine's own versions, such as "with Perl 5.44.0, gnuplot 6.0.0, by con on e" or "with Perl 5.44.0, R 4.6.1, ggplot2 4.0.3, by con on e". gnuplot's `<title>Gnuplot</title>` and `<desc>Produced by GNUPLOT ...</desc>` are taken out of its SVGs, as the note is all the metadata matplotlib's have. The R script writes the note itself, so a script written with `execute => 0` and run later writes it too; gnuplot cannot, so Perl writes it when it runs gnuplot, and a gnuplot script run by hand leaves its SVG without one. PNG and PDF files from either engine have no note.
    • `style` was accepted before as one of pyplot's functions, and wrote `plt.style(...)` into the script, which died there as "TypeError: 'module' object is not callable", since `plt.style` is a module. It now means only the above, and any other value than `'matplotlib'` or `'native'` is refused.
  • Fixed
    • A program that seeds `rand` with a fixed value, such as `srand 7`, no longer dies after enough runs with "Error in tempfile() using template /tmp/XXXXXXXXXX.py: Have exceeded the maximum number of attempts (1000) to open temp file". The scripts are kept in the temporary directory, and their names came from `rand` alone, so every run asked for the same ones and had to step past all those the runs before it had left. A script is now named `matplotlib-simple-<process>-<time>-<count>-XXXXXX.py` (or `.gp`, or `.R`), and the caller's random numbers are as they were.

Modules

Plots from Perl data structures, drawn by matplotlib, gnuplot or ggplot2, with one interface for every plot type

Provides

in lib/Matplotlib/Simple/Colors.pm
in lib/Matplotlib/Simple/Ggplot2.pm
in lib/Matplotlib/Simple/Gnuplot.pm
in lib/Matplotlib/Simple/Matplotlib.pm