# Using matplotlib in Perl 6 (part 2)

2017-03-05 23:00,

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

In Part 1 of this series, I managed to use matplotlib in Perl 6 to output a simple graph from the matplotlib tutorial. In this post, I will tackle the first graph in the matplotlib gallery, `barh_demo.py`.

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

plt.rcdefaults()
fig, ax = plt.subplots()

# Example data
people = ('Tom', 'Dick', 'Harry', 'Slim', 'Jim')
y_pos = np.arange(len(people))
performance = 3 + 10 * np.random.rand(len(people))
error = np.random.rand(len(people))

ax.barh(y_pos, performance, xerr=error, align='center',
color='green', ecolor='black')
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.set_xlabel('Performance')
ax.set_title('How fast do you want to go today?')

plt.show()```

Again, numpy is being used, but I figured Perl 6 can probably do whatever is needed natively, so I proceeded to convert the imports to Perl parlance (perlance?) and got started.

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

\$plt.rcdefaults();
my ( \$fig, \$ax ) = \$plt.subplots();```

As mentioned in the tail end of Part 1, Python likes scalar values, so from here on in I'm going to stick to using mostly scalar variables in my Perl code. I may also provide alternative methods of doing things if I think they are noteworthy or interesting. Now on with the show!

I need to create the example data... `people` is just your average list of strings. Perl has always had nice quoting construct to create a list of words, so that ones is as simple as

`my \$people = < Tom Dick Harry Slim Jim >;`

Now what's `numpy.arange` doing? I knew that `len(people)` was `5`, but I didn't know what `arange` was doing with that `5`. It turns out it simply creates an array of values starting at `0`, incrementing by one and up to `5`, ie. `[0, 1, 2, 3, 4]`. As seen in Part 1, I can use the handy Sequence operator for that, but creating lists like this is fairly common which is why Perl 6 also provides a convenient shortcut for it:

```my \$list = (0 ...^ 5); # Result: (0, 1, 2, 3, 4)
my \$list = ^5;         # same thing```

Of course, I can use a variable instead of a literal integer. As covered in Part 1, lists used in a numerical context are coerced to their number of elements. These features combined mean that my `y_pos` assignment looks like this.

`my \$y_pos = ^\$people;`

For the next two lists of values, `performance` and `error`, numpy is being used to generate some random values. Both values reference `len(people)`, and this equates to the number of random values returned: `5`. Perl has a fairly standard `rand` function that - without arguments - returns a random value between 0 and 1. However, I can use the "list repetition" operator (`xx`) to create a list of random values. Again referring to Part 1, I know that mathematical operations on a numpy array are equivalent to mapping that operation across each element, so I ended up with this.

```my \$performance = ( rand xx \$people ).map( 10 × * + 3 );
my \$xerr = rand xx \$people;```

In those 3 lines of code, The `\$people` list variable is used in a numerical context so it is evaluated to it's number of elements: `5`. You could always be more explicit in your code and say `\$people.elems` if you prefer.

You may have noticed I called my list of error values `xerr` instead of `error` and there's a good reason. Perl 6 provides a convenient syntax for passing named arguments (kwargs in Python) when a variable has the same name as the named argument.
Oh, and one more thing. Remember that `< word quoting >` syntax I used before? I can use that when passing named arguments too. Here's a quick illustration using an example function `foo()` that takes 1 positional parameter, and 1 named parameter.

```sub foo( \$positional, :\$named ) { ... }

# Calling the function
foo( 'bar', :named('baz') );

# Using the word-quoting construct
foo( 'bar', :named<baz> );

# or if I had a \$named variable
my \$named = 'baz';
foo( 'bar', :\$named );```

To some, it may seem odd to have so many ways to pass a named argument (and truthfully there's more) but I hope what comes through here is that the syntax tries to consistent in how it's used... But I digress... Less plodding and more plotting!

With the above out of the way, the rest of the code is pretty straight forward. Here's the final code.

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

\$plt.rcdefaults();
my ( \$fig, \$ax ) = \$plt.subplots();

# Example data
my \$people = < Tom Dick Harry Slim Jim >;
my \$y_pos = ^\$people;
my \$performance = ( rand xx \$people ).map( 10 × * + 3 );
my \$xerr = rand xx \$people;

\$ax.barh(
\$y_pos, \$performance,
:\$xerr, :align<center>, :color<green>, :ecolor<black>
);
\$ax.set_yticks(\$y_pos);
\$ax.set_yticklabels(\$people); Well that was mostly painless. The wrapper module is working as expected, and I was able to emulate a basic function of numpy with relative ease. I glanced back to the the Matplotlib gallery... Next in line was the `fill_demo`. Let's go!