Linux Format

Plotting pi...............................

Mihalis Tsoukalos plots pi in various languages, starting with Python, before displaying it as a coloured collection of random looking pixels…

-

Mihalis Tsoukalos plots pi in various languages, starting with Python, before displaying it as a coloured collection of random-looking pixels…

This month’s Python exploratio­n is all about the plotting of the digits of pi as an image, in this case in PNG format. However, this isn’t as simple as it seems, because you’ll need to know how to read and write to files, as well as how to specify the colour of a pixel in an image.

To make things even more interestin­g, this tutorial will present full code examples in Python 3, Perl and Go. Additional­ly, you’ll see Julia and R code that enables you to read a text file character by character so that you can understand the difference­s between general-purpose languages and programmin­g languages that were made with scientific computing in mind.

Pi is an irrational number, which means that its digits never end. Although there are many ways to calculate pi, this tutorial will enable you to display pi using a Python 3 module without the need to carry out any complex calculatio­ns. A forthcomin­g Linux Format article will talk about calculatin­g pi on your own with the accuracy that you desire.

Saving Private pi

The most handy, general-purpose and straightfo­rward solution is to save pi in a text file, which will be used each time you want to read the digits of pi. So, a small Python 3 script, called savePi.py, will do exactly this.

Bear in mind that the savePi.py script will utilise just one parameter, which will be the number of digits you want to obtain. It will print its output on the screen. Therefore, in order to save it, you’ll need to redirect the standard output to a text file.

As Python 3 comes with a whole range of scientific packages, it would be wise to use one of them in order to produce a manageable version of pi. In this case, the preferred package will be mpmath. Note that if mpmath isn’t already installed on your Linux system, you can install it as follows from the root account: # pip3 install mpmath

With mpmath installed, it’s easy to obtain pi – the Python 3 code of savePi.py is the next step: #!/usr/bin/env python3 import sys from mpmath import mp if len(sys.argv) == 1: print("Not enough arguments!") sys.exit(0) if sys.argv[1].isdigit():

accuracy = sys.argv[1] mp.dps = accuracy print(mp.pi)

The desired accuracy is set by defining the mp.dps property. Apart from that, you only have to print mp.pi. Executing savePi.py and saving its output is as easy as executing the following command: $ ./savePi.py 1000000 > pi1M.txt

All the implementa­tions will need to read the generated text file character by character or, more accurately, digit by digit. The Perl, Python 3 and Go programs will require four command line arguments: the two dimensions of the output image, the name of the output image and the filename of the text file with the digits of pi. The R and Julia implementa­tions won’t require any command line parameters for reasons of simplicity.

Figure 1 ( left) shows the output of savePi.py when calculatin­g pi with a relatively small accuracy as well as the output of the time() command when savePi.py computes pi with 1,000,000 (1M) and 10,000,000 (10M) digits on a relatively slow machine. As you can see, the latter calculatio­n took about 150 minutes...

Enough digits?

Well, the number of digits you’ll plot will directly affect the size of the plot. Generally speaking, there’s no point in plotting just 10 or even 100 digits of pi – you’ll need more in order to generate a good image/

So, for an image with 800x600 pixels, you’ll need 480,000 digits of pi—it’s clear that you shouldn’t underestim­ate the usefulness of the mpmath package. Finally, the Python 3 and Perl implementa­tions will use an array with 10 elements, and each element will be a different colour that will be used during the plotting phase. If you want to change the colours in the output image, you’ll need to edit that array.

The main problem that each implementa­tion should solve is defining an image with the desired dimensions and colouring each pixel of the image with the desired colour before saving the image on the disk. Each programmin­g language has its own approach and needs its own packages to perform the task, and this is what makes the task of creating many implementa­tions particular­ly interestin­g.

Each pixel has two coordinate­s, x and y. The value of the x coordinate is the quotient of the integer division between the number of the digits you’ve processed so far and the height of the image. In order to find the value of the y coordinate, you’ll need to find the remainder of the integer division between the number of the digits you’ve processed so far and the height of the image.

Using Python 3

The name of the file with the Python 3 implementa­tion will be pPi.py. But first you’ll learn how to create PNG images in Python 3 using the PIL module. The following Python 3 code, saved as tenten.py, shows how to create your own 10x10 image using the colours you want in Python 3 in order to better understand how pPi.py will work: #!/usr/bin/env python3 from PIL import Image n = 10 m = 10 filename = “test.png” image = Image.new('RGB’, (n, m)) image.save(filename, “PNG") img = Image.open(filename) pix = img.load() print(img.size) print(pix[5,5]) for x in range(1,10): for y in range(1,10):

pix[x, y] = x*y*x img.save("test.png")

The pix[x, y] statement defines the coordinate­s of the pixel that interests you, whereas the value of x*y*x defines the colour of the pixel, which in this case is a random colour. Once you have the code of tenten.py, you’ll only need to solve two more problems to be able to finish the task. The first one is reading the digits of pi from a text file one by one, and the other one is assigning the appropriat­e colour to each pixel based on the current digit. The most important code of pPi.py is the one that reads the text file with the value of pi digit by digit: f = open(textPi, ‘r')

 ??  ??
 ??  ?? Figure 1: savePi.py in action, as well as the output of the time(1) utility when timing the execution time of savePi.py on a relatively slow Linux machine.
Figure 1: savePi.py in action, as well as the output of the time(1) utility when timing the execution time of savePi.py on a relatively slow Linux machine.
 ??  ?? Figure 2: the output of the pPi.py Python 3 script when creating a PNG image file that’s 900 pixels tall and 800 pixels wide.
Figure 2: the output of the pPi.py Python 3 script when creating a PNG image file that’s 900 pixels tall and 800 pixels wide.

Newspapers in English

Newspapers from Australia