# Introduction to Python Programming. Section 3. Drawing, Plotting, and Data Visualization with Matplotlib

### 3 Drawing, Plotting, and Data Visualization with Matplotlib

#### 3.1 Objectives

In this section you will learn how to:

• Work with colors, RGB codes, and RGB color palettes.
• Plot lines, polylines, polygons, simple shapes, and graphs of functions.
• Fill objects with color and make holes into objects.
• Create parametric curves in the 2D plane and 3D space.
• Plot circles, ellipses, and spirals.
• Create wireframe plots, surface plots, contour plots, and use color maps.
• Use Matplotlib’s patches and artists.
• Create basic and advanced pie charts, donut charts, and bar charts.

#### 3.2 Why learn about data visualization with Python?

Python provides powerful data visualization libraries including Matplotlib, Seaborn, Mayavi and others. They are free but offer functionality comparable with expensive commercial software – that’s why they are increasingly popular not only with individual users but also at companies. In short, these are great job skills!

#### 3.3 RGB colors

Every color can be obtained by mixing the shades of red (R), green (G), and blue (B). These are called additive primary colors or just primary colors. The resulting color depends on the proportions of the primary colors in the mix. It is customary to define these proportions by an integer number between 0 and 255 for each primary color. So, the resulting color is a triplet of integers between 0 and 255. Examples of primary colors are red = [255, 0, 0], green = [0, 255, 0], blue = [0, 0, 255]. These colors are shown in the following Fig. 5 (left). When the R, G, and B values are the same, the result is a shade of grey. With [0, 0, 0] one obtains black, with [255, 255, 255] white. Other examples are shown in Fig. 5 (right).  Fig. 5: Left: primary colors (red, green, blue). Right: shades of grey.

#### 3.4 Secondary colors

You already know that by primary colors we mean colors where only one of the R, G, B components is nonzero. Analogously, secondary colors are colors where only two of the R, G, B components are nonzero. Fig. 6 shows the three most well-known secondary colors cyan, pink and yellow along with their RGB codes. Fig. 6: Left: brightest cyan color [0, 255, 255]. Middle: brightest pink color [255, 0, 255]. Right: brightest yellow color [255, 255, 0].

Keep in mind that the two nonzero components do not have to be the same. For instance, the colors [0, 214, 138], [50, 0, 100] and [145, 189, 0] are also secondary.

#### 3.5 Figuring out RGB codes

The easiest way to find the RGB code for a particular color you need is to google it. For example, to obtain the RGB color of violet color, type "violet RGB code" in your web browser. The result of the query is shown in Fig. 7. Fig. 7: Searching the web for the RGB code of the violet color.

#### 3.6 RGB color palettes

Sometimes one needs to find the right color for a specific application. In this case, it may be useful to browse some RGB palettes. In order to find them, search for "RGB color palette". There will be many results similar to each other, as shown in Fig. 8. Fig. 8: Sample RGB color palette.

Hovering your mouse over a color, or clicking on it, will reveal its RGB code.

#### 3.7 Starting with Matplotlib

Matplotlib is a powerful Python visualization library originally written by John D. Hunter, an American neurobiologist. The library is fully compatible with Numpy and other Python libraries. It is customary to import it by typing import matplotlib. pyplot as plt. As a Hello World project, let’s plot a polyline!

The plot() function takes two arrays: x-coordinates and y-coordinates of points in the xy plane. Between the points, the curve is interpolated linearly. Let us illustrate this on a simple example with just five points [0, 0], [1, 2], [2, 0.5], [3, 2.5] and [4, 0]:

import matplotlib.pyplot as plt
x = [0.0, 1.0, 2.0, 3.0, 4.0]
y = [0.0, 2.0, 0.5, 2.5, 0.0]
plt.clf()
plt.plot(x, y)
plt.show()

The commands plt.clf(), plt.plot() and plt.show() do clear the canvas, plot the graph, and display the image, respectively. The output is shown in Fig. 9. Fig. 9: Polyline with five points.

If the first and last points were the same, then the polyline would form a closed loop and one would obtain a polygon.

#### 3.8 Two ways to specify color

The default blue color can be changed by passing an optional argument color to the plt.plot() function. With color = ’pink’ we obtain a pink polyline. Fig. 10: Setting pink color via plt.plot(x, y, color = ’pink’).

Matplotlib contains many predefined colors, so it’s always worth checking whether your color is available before resorting to RGB codes.

But specialty colors of course must be defined using RGB codes. For example, Kelly-Moore Oakwood color has the RGB code [186, 164, 138]. Before passing it into the plt.plot() function, one has to normalize the values (divide them by 255) to lie between 0 and 1. For the Kelly-Moore Oakwood the normalized RGB code is [186/255, 164/255, 138/255]:

import matplotlib.pyplot as plt
x = [0.0, 1.0, 2.0, 3.0, 4.0]
y = [0.0, 2.0, 0.5, 2.5, 0.0]
plt.clf()
plt.plot(x, y, color = [186/255, 164/255, 138/255])
plt.show()

The corresponding output: Fig. 11: Kelly-Moore Oakwood color [186, 164, 138].

#### 3.9 Making axes equally scaled

Sometimes one does not mind that axes are not equally scaled - such as in the previous example. Then Matplotlib tries to make the best use of the entire viewing area. But it might become an issue when one wants to display a geometrical object with accurate proportions. For example, displaying a square with differently-scaled axes does not really work, as shown in Fig. 12. Fig. 12: Plotting a square with differently-scaled axes.

To correct this, it is enough to add the command plt.axis(’equal’):

import matplotlib.pyplot as plt
x = [1, 2, 1, 0, 1]
y = [0, 1, 2, 1, 0]
plt.clf()
plt.axis(’equal’)
plt.plot(x, y)
plt.show()

The result is shown in Fig. 13. Fig. 13: Same square as above, but now with equally-scaled axes.

#### 3.10 Filling shapes with color

A shape can be filled with color by using plt.fill() instead of plt.plot(), as shown in Fig. 14. Fig. 14: Replacing plt.plot() with plt.fill().

#### 3.11 Borders

Have you noticed a thin black border in Fig. 14? One can make it thicker by including an optional parameter linewidth (or just lw) in plt.fill(): Fig. 15: Making the border thicker via plt.fill(x, y, lw = 4).

The same optional parameter can be used to change the line width when plotting polylines. To eliminate the border, one can set lw = 0. This is shown in Fig. 16. Fig. 16: Eliminating the border with lw = 0.

#### 3.12 Interrupting lines

Lines can be interrupted with the keyword None. For example, the following code will plot three separate lines [0, 0] [1, 0], [1, 1] [2, 1] and [2, 2] [3, 2]:

import matplotlib.pyplot as plt
x = [0, 1, None, 1, 2, None, 2, 3]
y = [0, 0, None, 1, 1, None, 2, 2]
plt.clf()
plt.axis(’equal’)
plt.plot(x, y, lw = 2)
plt.show()

This is the corresponding output: Fig. 17: Interrupting lines with the keyword None.

#### 3.13 Making holes

To make a hole into a shape, the boundary of the shape and the boundary of the hole must have opposite orientations. What do we mean by orientation? Look at these two arrays which correspond to the square from Fig. 16:

x = [1, 2, 1, 0, 1]
y = [0, 1, 2, 1, 0]

This polyline is connecting the points [1, 0] [2, 1] [1, 2] [0, 1] [1, 0] in the counter-clockwise direction. Let’s say that we want to make a square hole of dimensions (0.75, 1.25) × (0.75, 1.25). This will be a polyline connecting the points [0.75, 0.75] [1.25, 0.75] [1.25, 1.25] [0.75, 1.25] [0.75, 0.75]. Except, this orientation also is counter-clockwise so it would not work. We need to flip the orientation of the hole to clockwise: [0.75, 0.75] [0.75, 1.25] [1.25, 1.25] [1.25, 0.75] [0.75, 0.75]. Then it will work: Fig. 18: Holes are made using polylines of opposite orientation.

Here is the corresponding code:

import matplotlib.pyplot as plt
x = [1, 2, 1, 0, 1, None, 0.75, 0.75, 1.25, 1.25, 0.75]
y = [0, 1, 2, 1, 0, None, 0.75, 1.25, 1.25, 0.75, 0.75]
plt.clf()
plt.axis(’equal’)
plt.fill(x, y, color = ’purple’)
plt.show()

#### 3.14 Plotting functions of one variable

Let’s say that we want to plot the function f(x) = sin(x) in the interval (0, 2π). The array of x-coordinates of equidistant points between 0 and π can be created easily using Numpy’s function linspace():

import numpy as np
x = np.linspace(0, 2*np.pi, 101)

Here 101 means the number of points in the division, including endpoints. Hence, with 101 points one subdivides the interval into 100 equally long subintervals. Increasing this number will improve the resolution and vice versa. Next, the array of y-coordinates of the points is obtained via

y = np.sin(x)

The last part you already know:

import matplotlib.pyplot as plt
plt.clf()
plt.plot(x, y)
plt.show()

The output is shown in Fig. 19. Fig. 19: Plotting sin(x) in interval (0, 2π).

#### 3.15 Line style, label, and legend

The plot can be made nicer by adding a label. When adding a label, one needs to call the function plt.legend() to display the legend. Also the line color and line style can be changed. Let us start with adding a label:

plt.plot(x, y, b-, label = ’Solid blue line’)
plt.legend()
plt.show()

The output is shown in Fig. 20. Next let us change the color to red and line style to dashed:

plt.plot(x, y, r--, label = ’Dashed red line’)
plt.legend()
plt.show()

The output is shown in Fig. 21. Fig. 21: Using dashed red line.

The graph can be plotted using green color and small dots rather than a solid or dashed line:

plt.plot(x, y, g., label = ’Dotted green line’)
plt.legend()
plt.show()

The output is shown in Fig. 22. Fig. 22: Using dotted green line.

Last, let us stay with green color but make the dots bigger:

plt.plot(x, y, go, label = ’Bigger green dots’)
plt.legend()
plt.show()

The output is shown in Fig. 23. Fig. 23: Same graph using bigger green dots.

Line style can also be set separately using the optional parameter linestyle (or just ls) of the function plt.plot(). This parameter can have the values ’solid’, ’dashed’, ’dashdot’, ’dotted’, ’-’, ’–’, ’-.’, and ’:’.

#### 3.16 Showing the grid

When plotting functions, displaying the grid makes reading the values off the graph easier. The grid can be displayed using plt.grid():

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 101)
y = np.sin(x)
plt.clf()
plt.plot(x, y, label=’sin(x)’)
plt.axis(’equal’)
plt.grid()
plt.legend()
plt.show()

The output is shown in Fig. 24. Fig. 24: Scaling axes equally and showing grid.

The scaling of axes can be returned to the automatic fit option via plt.axis(’auto’) if needed.

Plot limits can be set using the plt.xlim() and plt.ylim() functions after plt. plot(). For example, we can stretch the sine function from Fig. 24 to span the entire width of the canvas as follows:

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 101)
y = np.sin(x)
plt.clf()
plt.plot(x, y, label=sin(x))
plt.xlim(0, 2*np.pi)
plt.axis(’equal’)
plt.grid()
plt.legend()
plt.show()

The output is shown in Fig. 25. Fig. 25: Setting plot linits on the horizontal axis to 0 and 2π.

#### 3.18 Plotting multiple functions at once

Multiple graphs can be displayed in one plot by just leaving out the plt.clf() command between them. For illustration, let us display the graphs of three different functions together:

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0.5, 5, 1.0)
y1 = 1 / x
y2 = 1 / (1 + x**2)
y3 = np.exp(-x)
plt.axis(’equal’)
plt.clf()
plt.plot(x, y1, label=y1)
plt.plot(x, y2, label=y2)
plt.plot(x, y3, label=y3)
plt.legend()
plt.show()

The output is shown in Fig. 26. Fig. 26: Plotting graphs of functions 1∕x, 1(1 + x2) and e-x in interval (0.5, 5).

The plt.plot() command in Matplotlib has many options. For a complete list visit the reference page https://matplotlib.org/api/_as_gen/matplotlib.
pyplot.plot.html#matplotlib.pyplot.plot.

#### 3.19 Plotting circles

The concept of plotting based on two arrays of x and y coordinates allows us to plot parametric curves such as circles, ellipses, and spirals. Let’s begin with a circle of radius R centered at [cx,cy] whose parametric equation is The parameter t is defined in the interval (0, 2π). The code:

import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 2*np.pi, 101)
x = cx + R*np.cos(t)
y = cy + R*np.sin(t)
plt.clf()
plt.axis(’equal’)
plt.plot(x, y)
plt.show()

The output for R = 1 and cx = cy = 0 is shown in Fig. 27. Fig. 27: Plotting a circle of radius R = 1 centered at [0, 0].

#### 3.20 Making a circular hole

Let’s briefly return to Fig. 18 where we made a hole into a square using a polyline of opposite orientation: Fig. 28: Shape with a 0.5 × 0.5 square hole from Fig. 18.

Now we want to create a circular hole with radius R = 0.25 and centered at [1, 1]: Fig. 29: Circular hole of radius R = 0.25 centered at [1, 1].

Since the outer shape’s boundary is oriented counter-clockwise and so is the circle, this would not work. But it is easy to change the orientation of the circle to clockwise: Here is the corresponding code:

import numpy as np
import matplotlib.pyplot as plt
xs = [1, 2, 1, 0, 1, None]
ys = [0, 1, 2, 1, 0, None]
t = np.linspace(0, 2*np.pi, 101)
xc = 1 - 0.25*np.cos(t)
yc = 1 + 0.25*np.sin(t)
x = xs + list(xc)
y = ys + list(yc)
plt.clf()
plt.axis(’equal’)
plt.fill(x, y, color = ’purple’)
plt.show()

Notice that we used list(xc) and list(yc) to cast Numpy arrays xc and yc to lists. This was necessary in order to add them to the lists xs and ys. We will explain operations with lists in more detail later.

#### 3.21 Plotting ellipses

If you know how to plot a circle, you also know how to plot an ellipse. All you need to do is replace the radius R with two different values in the X and Y directions. To illustrate this, let’s replace the radius 0.25 in the previous example with 0.5 in the X direction and 0.3 in the Y direction. Here is the new version of the corresponding two lines:

xc = 1 - 0.5*np.cos(t)
yc = 1 + 0.3*np.sin(t)

Otherwise the code remains unchanged. The output is shown in Fig. 30. Fig. 30: Converting a circle of radius 0.25 into an ellipse with radii 0.5 and 0.3.

#### 3.22 Plotting spirals

If you know how to plot a circle, you also know how to plot a spiral. All you need to do is make the radius increase with angle t. Let us illustrate this on a spiral that is parameterized by x(t) = t cos(t) and y(t) = t sin(t) in the interval (0, 10) for t: Fig. 31: Plotting a spiral.

The complete code for the spiral is

import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 10, 101)
x = t*np.cos(t)
y = t*np.sin(t)
plt.clf()
plt.plot(x, y)
plt.show()

#### 3.23 Parametric curves in the 3D space

For 3D plots it is practical to use Matplotlib’s mplot3d toolkit. Parametric 3D curves are defined analogously to planar curves that we plotted in the previous paragraphs. 3D curves are sequences of linearly interpolated 3D points represented via three arrays of X, Y and Z coordinates. As an example, let’s plot the curve Here the parameter t lies in the interval (-2, 2).

# Import Numpy and Matplotlib:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
# Setup the 3D plot:
plt.gca(projection=3d)
# Define the division and the curve:
t = np.linspace(-2, 2, 101)
x = (1 + t**2) * np.sin(2 * np.pi * t)
y = (1 + t**2) * np.cos(2 * np.pi * t)
z = t
# Plot the curve and show the plot:
plt.plot(x, y, z, label=Parametric 3D curve)
plt.legend()
plt.show()

Compared to plotting planar curves, the only new thing is setting up the 3D plot via plt.gca(projection=’3d’). Here, gca means "get current axes". It is a technicality that you don’t have to worry about. The output is shown in Fig. 32. Fig. 32: Plotting a parametric 3D curve.

#### 3.24 Wireframe plots of functions of two variables

The Matplotlib’s mplot3d toolkit provides several ways to plot graphs of functions of two variables. First let’s create a wireframe plot of the graph of the function in the square (-π,π) × (-π,π):

# Import Numpy and Matplotlib:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
# Define intervals on the ’x’ and ’y’ axes and divisions:
x = np.linspace(-3, 3, 31)
y = np.linspace(-3, 3, 31)

# Create Cartesian grid:
X, Y = np.meshgrid(x, y)
# Calculate values at grid points:
Z = np.sin(X) * np.sin(Y)
# Create 3D axes and plot the data:
axes = plt.axes(projection=’3d’)
axes.plot_wireframe(X, Y, Z, rstride=1, cstride=1, linewidth=1)
# Show the plot:
plt.show()

The parameters rstride (row stride) and cstride (column stride) can be used to make the plot coarser when they are set to 2, 3, etc. The output is shown in Fig. 33. Fig. 33: Wireframe plot of the function f(x,y) = sin(x) sin(y).

#### 3.25 Surface plots

Surface plot can be obtained by replacing in the above code

axes.plot_wireframe(X, Y, Z, rstride=1, cstride=1, linewidth=1)

with

axes.plot_surface(X, Y, Z, rstride=1, cstride=1, linewidth=1)

The output is shown in Fig. 34. Fig. 34: Surface plot of the function f(x,y) = sin(x) sin(y).

#### 3.26 Color maps

Function plot_surface accepts an optional parameter cmap ("color map"). For example, selecting cmap=’jet’,

axes.plot_surface(X, Y, Z, rstride=1, cstride=1, linewidth=1,
cmap=’jet’)

yields Fig. 35: The "jet" color map.

Another choice cmap=’viridis’ yields Fig. 36: The "viridis" color map.

In the next example we will use the color map cmap=’ocean’, finer division np. linspace(-3, 3, 61), and hide the black lines by setting linewidth=0. Fig. 37: The "ocean" color map and linewidth=0.

Last, let’s show the color map cmap=’rainbow’: Fig. 38: The "rainbow" color map.

Matplotlib provides many additional color maps, make sure to check them out at https://matplotlib.org/examples/color/colormaps_reference.html!

#### 3.27 Contour plots

Contour plot can be obtained by replacing in the above code the line

axes.plot_wireframe(X, Y, Z, rstride=1, cstride=1, linewidth=1)

with

axes.contour(X, Y, Z, num_contours)

where num_contours is the desired number of contours. If no color map is selected, Matplotlib uses "jet". Sample output with num_con tours = 50 is shown in Fig. 39. Fig. 39: Contour plot with 50 contours.

The contour function supports color maps. For example, with

axes.contour(X, Y, Z, num_contours, cmap=’terrain’)

one obtains the following contour plot: Fig. 40: The color map "terrain".

#### 3.28 Changing view and adding labels

Sometimes the default view is not optimal, in which case one can change the elevation and azimuthal angles via the function view_init. By elevation angle we mean the angle between the XY plane and the line connecting the camera and the origin [0, 0, 0]. By azimuthal angle we mean the angle of rotation about the Z axis. With axes defined as in the above code, calling

print(axes.elev, axes.azim)

will reveal the current values of these two angles (their default values are 30 and -60 degrees BTW). To change them to (say) 70 and 40 degrees, add the following line right after the line axes = plt.axes(projection=’3d’):

axes.view_init(70, 40)

The result is shown in Fig. 41. When changing the view, it is a good idea to put labels on the X, Y and Z axes:

axes.set_xlabel(’X’)
axes.set_ylabel(’Y’)
axes.set_zlabel(’Z’) Fig. 41: Changing elevation and azimuthal angles to 70 and 40 degrees, respectively.

We will now leave the mplot3d toolkit but we invite you to explore more of it at http://matplotlib.sourceforge.net/mpl_toolkits/mplot3d.

#### 3.29 Patches and artists

Now that you know the mechanics of creating various 2D shapes, graphs and curves via polylines, we can shift to a higher gear and explore Matplotlib’s patches (patch = 2D shape). The patches provide a quicker way to create various 2D shapes including triangles, squares, rectangles, polygons, circles, ellipses, arcs, arrows, rectangles with round corners, and more. For a complete list of these shapes see

https://matplotlib.org/api/patches_api.html
On top of what you already can do using polylines, patches can be transparent (the function fill that we have used so far does not support transparency). Moreover, patches can be rotated. We could show you how to do this with our polylines but we would need some advanced linear algebra and Python programming. In short - Matplotlib’s patches make all of this very easy. All one needs is to specify a few parameters while defining the 2D shapes.

Let’s show an example by creating three ellipses e1, e2 and e3, centered at [0, 0] and rotated by 0, 60 and 120 degrees, respectively. They will all have diameters 4 in the X direction and 1 in the Y direction, respectively, and 50% transparency (alpha = 0.5). Then we will add a red circle c1 of radius 0.4. Adding each 2D shape requires adding a new "artist". Here is the code:

import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Ellipse
e1 = Ellipse((0, 0), 4, 1, alpha=0.5, angle=0, color=’pink’)
e2 = Ellipse((0, 0), 4, 1, alpha=0.5, angle=60, color=’cyan’)
e3 = Ellipse((0, 0), 4, 1, alpha=0.5, angle=120, color=’yellow’)
c1 = Circle((0, 0), 0.4, color=’red’)
plt.axis(’equal’)
plt.xlim(-3, 3)
plt.ylim(-2, 2)
plt.show()

Do not worry about the calls to gcf ("get current figure"), gca ("get current axes") and add_artist. These are technicalities whose sole purpose is to add a new shape to the current figure. The output: Fig. 42: Three ellipses rotated by 0, 60 and 120 degrees, and a circle.

#### 3.30 Pie charts

Matplotlib’s pie charts are an elegant way to report the breakdown of an ensemble into parts. It provides the function pie for that. The simplest example of a pie chart involves just 7 lines of code:

import matplotlib.pyplot as plt
data = [450, 550, 300]
labels = [cats, dogs, mice]
plt.clf()
plt.axis(’equal’)
plt.pie(data, labels=labels)
plt.show()

The code is self-explanatory. Its output is shown in Fig. 43. Fig. 43: The most basic pie chart.

Next let’s present a fancier pie chart showing the production of an electronic company that sells TVs, computer monitors, cameras, printers and scanners. Make sure to read the comments in the code:

# Import Matplotlib:
import matplotlib.pyplot as plt
# This time there are five sections:
labels = [TVs, Monitors, Cameras, Printers, Scanners]
# Fractions in percent:
fractions = [15, 30, 5, 40, 10]
# ~Monitors~ section will be highlighted by moving
# out of the chart by 0.05:
explode = (0, 0.05, 0, 0, 0)
# Create the pie chart. The ~autopct~ parameter formats the
# numerical percentages. Shadow can be suppressed by setting
# it to False:
plt.clf()
plt.pie(fractions, explode=explode, labels=labels,
# Display the pie chart:
plt.axis(’equal’)
plt.show()

The output is shown in Fig. 44. Fig. 44: Fancier pie chart.

The autopct option determines the numerical format in which the numbers inside the pie chart will be displayed. The letter f stands for a floating-point number. The 1.1 means that one decimal digit will be present after the decimal point (1.2 would print the percentages with two digits after the decimal point, etc.). The parameter shadow indicates whether a shadow will be used. It can be set to True or False.

#### 3.31 Donut charts

A special case of the pie chart is the "donut chart" which has a white circle inserted at the center. This time we will also show you how to use custom colors and how to rotate the pie chart. Do not worry if you do not understand all the details in the following code. The main things are self-explanatory. Hexadecimal RGB color codes will be discussed in detail later. You should understand the code well enough to be able to take an example like this and tweak it to display your own data.

# Import Matplotlib:
import matplotlib.pyplot as plt
labels = [TVs, Monitors, Cameras, Printers, Scanners]
fractions = [15, 30, 5, 40, 10]
# Custom colors:
colors = [’#ff9999’,’#66b3ff’,’#99ff99’,’#ffcc99’,’#e6e6fa’ ]
explode = (0, 0, 0, 0, 0) # No explode this time.
# Create the pie chart:
plt.clf()
plt.pie(fractions, colors=colors, labels=labels,
autopct=’%1.1f%%’, startangle=130,
pctdistance=0.85, explode=explode)
# Draw a white circle at the center:
center_circle = plt.Circle((0, 0), 0.70, facecolor=’white’)
# Display the pie chart:
plt.axis(’equal’)
plt.show()

The output is shown in Fig. 45. Fig. 45: Donut chart with custom colors and rotation.

#### 3.32 Bar charts

Bar charts are a great way to visualize sequential data such as, for example, the yearly growth of a company’s revenues, number of daily visits to a web page, weekly rate of unemployment in the state, etc. The simplest bar chart involves just 6 lines of code:

import matplotlib.pyplot as plt
data = [450, 550, 300]
positions = [1, 2, 3]
plt.clf()
plt.bar(positions, data)
plt.show()

The array [1, 2, 3] specifies the positions on the horizontal axis where the bars begin. The default width of the bars is 0.8 and it can be adjusted via the parameter width of the bar function. The output is shown in Fig. 46. Fig. 46: Basic bar chart.

Next let us present a more advanced bar chart that shows a company’s growth both in the total number of employees and the yearly increments. Again, do not worry if you do not understand all details in the code. You need to understand enough to be able to tweak such an example to display your own data - increase or decrease the number of columns, change the values, etc.

# Import Matplotlib, and define totals and increments:
import matplotlib.pyplot as plt
totals = (20, 25, 32, 42, 61)
increments = [5, 7, 10, 19, 30]

# Positions and width of the bars:
positions = [0, 1, 2, 3, 4]
width = 0.4

# Create figure and subplot, define bars:
fig = plt.figure()
bars1 = ax.bar(ind, totals, width, color=y)
bars2 = ax.bar(ind + width, increments, width, color=b)

ax.set_ylabel(Numbers)
ax.set_title(Number of employees)
ax.set_xticks(ind + width)
ax.set_xticklabels( (2008, 2009, 2010, 2011, 2012) )

# Function to add numbers above bars:
def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width() / 2,
height + 0.02 * max(totals), %d%int(height),
ha = center, va = bottom)

# Create the bars and display the bar chart:
autolabel(bars1)
autolabel(bars2)
plt.show()

The output is shown in Fig. 47. Fig. 47: Bar chart showing a company’s growth.

The functionality provided by Matplotlib is so extensive that we could spend an almost unlimited amount of time exploring it. A huge number of examples are available online. At this point we need to move on to other aspects of Python, but we invite the reader to learn more about Matplotlib at http://matplotlib.org.

#### 3.33 Statistical data visualization with the Seaborn library

Another powerful Python library for data visualization is Seaborn:

https://seaborn.pydata.org
This library is based on Matplotlib, and its primary goal is to facilitate the visualization of statistical data such as densities, histograms, kernel density estimations (KDEs), heatmaps, box plots, scatter plots, violin plots, etc. A nice overview of the various types of visualizations that can be done with Seaborn can be found at
http://seaborn.pydata.org/examples
Seaborn is free and distributed under the BSD License. Fig. 48 shows a sample visualization of histograms and KDEs. Fig. 48: Sample histograms and kernel density estimations (KDEs).

#### 3.34 Interactive scientific data visualization with Mayavi2

We can’t finish this section without mentioning Mayavi:

http://docs.enthought.com/mayavi/mayavi
Mayavi, and in particular the newer version Mayavi2 is a general purpose, cross-platform tool for 3D scientific visualization of scalar, vector, and tensor data in two and three spatial dimensions. It can be used both in an interactive mode via a GUI, and as a library from withim Python programs. Mayavi2 is free and distributed under the BSD License. Fig. 49: Graphical user interface (GUI) of Mayavi2.