Writing About Graphing with matplotlib
Today I wanted to draw some graphs. I started out using Wolfram Alpha’s excellent plot() functionality but wanted something that I would be able to use offline too. Mathematica & Matlab are beyond my requirements and Excel/Google Sheets/the Apple one don’t give me enough flexibility.
I chose to use Python and in particular the matplotlib library’s pyplot module. I don’t really use Python so before I talk about how I got basic graphs working, let’s look at getting Python set up on OSX:
Python Setup
As Python 3 is the latest official version, we should try to use that if possible. The quickest way to get that is by installing it with brew:
To verify this has worked, start a new terminal session and run python3
. You should now see something like this:
The default brew Python 3 installation includes the pip package manager. As with the python executable, pip is suffixed with ‘3’ to distinguish it from a pip installation for python 2. You can verify its presence by querying its version:
Basic Graphing
We need the matplotlib library which we can install with pip:
Now we’re ready to make some graphs in Python! This is the script I used to draw my graphs:
In this example, I want to run a series of equations of the form y = f(x)
so I need to create some x values for the data points and then have some way of representing the equations.
I want my x values to go from -10 to 10 so I first tried range(-10, 11)
, but this only gives me a granularity of 20 coordinates. Instead I used a for comprehension - creating a range from -1000 up to and including 1000, and then dividing each coordinate by 100 which results in 2000 floating point x values between -10 and 10.
I create several lambdas representing equations (y = 1, y = x, y = x^2, y = x^3, y = x^4, y = log(x)) and stash these in an array. I want to use the complex logarithm for which y values exist for negative x, but not for 0 so at this point I exclude 0 from my test_data using the filter function and a lambda predicate.
Setting up the graph layout is simple - I add lines through the origin with the axhline
and axvline
functions and set the limits of the graph to positive and negative 10 for both axes with xlim
and ylim
.
To plot the graphs, I iterate over the array of equation lambdas and plot the test data against the test data mapped to the current lambda. Finally I output the graph to a file called “out.png” with the savefig
function:
Bonus 1: Atom Setup
I like the Atom editor, and it comes with support for Python out of the box. However, there are two extra packages that make Python editing nicer for a beginner like me. These are autocomplete-python which provides autocompletion functionality as you might expect, and linter-pep8 which applies the pep8
standards tool to your code and tells you when you’re not formatting it in the correct way.
First you need pep8:
And then you need to install the packages which you can either do through the Atom UI, or with the Atom Package Manager as follows:
Bonus 2: Pythonista
There exists a splendid iOS app called Pythonista which contains an implementation of Python and a well featured editor. Pythonista also comes packaged with matplotlib, so out of curiosity I copied my graph script in, changing the plt.savefig("out.png")
line to plt.show()
to display the graph rather than write it to a file, and it worked straight away:blo