## Using matplotlib in Perl 6 (part 1)

2017-03-04

This is Part of a series. You can start at the Intro here

Looking at the graphs in the Matplotlib tutorial, the first one is a straight line (boring). The second is a few red dots plotting a curve (getting better). The 3rd graph looked a more interesting: Three curved plots consisting of different patterns and colors. Here's the Python code.

```import numpy as np
import matplotlib.pyplot as plt

# evenly sampled time at 200ms intervals
t = np.arange(0., 5., 0.2)

# red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()
```

I ran it in python to confirm it worked as expected (it did). I then proceeded to copy and paste the code into a new Perl 6 file and changed the `import` statements to `use` statements.

```use Matplotlib;
my \$plt = Matplotlib.new;
```

Now for the data... The `t` values were generated by a numpy function called `arange`. I didn't know what that did, and rather than wrap numpy as well, I figured I could probably do whatever it was doing with Perl 6. As the comment suggested, it was a simple number sequence. Perl 6 has a handy Sequence operator for just this sort of thing.

```my @t  = 0, 0.2 ...^ 5;
```

This defines a Sequence starting at 0, followed by 0.2, then increasing at the same interval until is gets up to (`^`) 5. If I wanted to include 5 in the Sequence, I would just drop the `^`. Using some well placed print statements, I confirmed by `@t` values were the same as the python version.

I then pasted the rest of the Python code into my Perl script, inserted a `@` in front of each `t` and ran it. Things did not go as planned. Well, I got a graph, but it wasn't quite right Some of you might have already guessed where I went wrong. Spoiler, I don't have any experience with numpy arrays (or numpy for that matter). A few more print statements let me know where I was going wrong. You see, when referring to a list (or array) in a numerical context, Perl will coerce the array to it's number of elements

```my @t = (2, 3, 4);
@t ** 2; # Result: 9
```

However numpy arrays will apply that operation to each value in the array. I could create an object in Perl 6 that behaves the same way, but for now I'll just use Perl's map function which is perfectly apt for this sort of thing. Perl 6 provides a number of ways to map values in an array: I can be very explicit, or very succinct.

```@t.map(-> \$x { \$x ** 2 }) # Result: (4, 9, 16)
@t.map(*²)                # same thing
```

Note the lack of curlies `{}` in the second example. This is a special syntax where `*` takes on the value of whatever value it was passed. In fact, Perl 6 actually refers to that `*` as `Whatever`. This `WhateverCode` is best suited for simple operations, which perfectly describes a binary mathematical operation such as exponentiation.

Additionally, Perl contains quite a few unicode operators; My favourites are `×` for multiplication and `÷` for division, instead of the historical compromise of `*` and `/`. In the second example above, I am using the superscript of 2 (`²`) to raise Whatever (`*`) to the power of 2.

I modified my arguments accordingly and ran it again. Another graph! This one also had 2 dots... But they were in a different place to last time, so that's progress, right? I looked at the gist again and noticed the arguments to `plot` were inside square brackets. Accepting it was probably due a difference in how each language handled positional arguments, I diligently wrapped my arguments to `plot` in square brackets.

```\$plt.plot([
@t, @t,         'r--',    # red dashes
@t, @t.map(*²), 'bs',     # blue squares
@t, @t.map(*³), 'g^'      # green triangles
]);

\$plt.show();
```

This time when I ran it and was delighted when a graph identical to the one on the tutorial appeared before my eyes. Wondering about those square brackets, I played around a little with the call to `plot`. I quickly learned that Python prefers to be given what Perl calls "scalar" variables. In simple terms, a scalar is a variable that Perl will treats as a single "thing". Passing a Perl array of 3 `@things` to a Python function would cause those 3 values to get expanded out to 3 positional arguments. Creating a scalar list `\$things` or coercing `\$@things` to be passed in a scalar context works much better.

With regard to that `map`, it seems that by giving the `map` directly to `plot`, it was more "listy" than scalar. By assigning the result to a scalar first, I could then pass those values to `plot` without having to wrap all the arguments in square brackets, like so..

```my \$t  = [0, 0.2 ...^ 5];
my \$t2 = \$t.map(*²);
my \$t3 = \$t.map(*³);

\$plt.plot(
\$t, \$t,  'r--',    # red dashes
\$t, \$t2, 'bs',     # blue squares
\$t, \$t3, 'g^'      # green triangles
);

\$plt.show();
```

So that about wraps up Part 1. This graph was kind of interesting, but I knew matplotlib was capable of more. I felt no great excitement from the other images in the tutorial, so headed off to the gallery to see what else I could sink my teeth into.

To be continued...