Adjective Noun

Using matplotlib in Perl 6 (intro)

2017-03-04 20:00, Tags: perl python matplotlib

I'm a network engineer by trade, but I write a lot of scripts at work to automate or simplify aspects of my job for myself and my colleagues. Most of the tools I write are predominantly doing text parsing, and I use Perl 5 for that. I use Python on occasion where I feel like it's a better fit, but mostly I prefer Perl. I'm also a fan of Perl 6 and have been playing with it since the official release in December '15.

I've been aware of matplotlib (and numpy) for a while, but in my line of work I've never really had a need to use either. That said, I have the awareness that matplotlib is a great plotting library, something that Perl 6 is lacking, but not all is lost.

While perusing the comments in this HackerNews thread, someone linked to a gist that used Inline::Python (a module for executing Python code and accessing Python libraries from Perl 6) to wrap matplotlib in a Perl 6 class. Was this really all that I needed to do to use matplotlib in Perl 6? I headed to matplotlib tutorials page to try it out.


So that's what this series will be about. I found the process of figuring out how to use matplotlib in Perl 6 interesting, so decided to write about it. Now, I don't want to lead anyone down the garden path, so I'm putting this up front. After the first plot, I discovered that wrapper in the gist will fail when passing named arguments. I've added a comment to that gist about this. There are also more shortcomings to this module, but I'll cover those in later parts to this series.

The wrapper module I'll be working with for the first few diagrams looked like this, though it will change as I discover limitations.

class Matplotlib {
    use Inline::Python;
    has $!py;

    submethod BUILD() {
        $!py = Inline::Python.new();
        $!py.run('import matplotlib.pyplot')
    }

    method FALLBACK($name, |c) {
        $!py.call('matplotlib.pyplot', $name, |c);
    }
}

Essentially this class creates a new Inline::Python object and runs import matplotlib.pyplot when it get instantiated. There are no normal methods defined, so any class methods route to the FALLBACK method, which takes the name of that method and calls the matplotlib.pyplot method of the same name.

But what's that |c? That's the syntax for a special type in Perl 6, a Capture. Any additional argument are "captured" in the Capture object. A capture doesn't do any unpacking. It encases them in carbonite and ships them off to wherever to be unpacked later. Capture objects are very useful when you want to punt arguments to another function.

There's also an Inline::Python module for Perl 5 if you want to try to use that with pyplot. I took a stab at it but ran into difficulty with named arguments, but I gave up pretty quickly since Perl 6 was nicer for the number-y stuff.

Anyway, this wrapper module will cover most generic uses of pyplot, and I get a few plots in before I hit my first hurdle, so head on over to Part 1 to start the journey.

If you'd like to play around with my modules as they existed after this series, I've put them up in a gist. You're welcome to fork them and do whatever you will.