matplotlib intro

You can make plots with any tool you like. But we may help you a little with the open source matplotlib library for scientific ploting, which runs with Python.


References:

Get ready

You need to install Python3.x

Check the existence of Python3 by typing python3 --version in your terminal (Powershell for Windows). Otherwise, we recommend to use conda to manage your Python environments:

  1. install miniconda (Linux, macOS or Windows).
  2. create a new environment: conda create --name myenv python=3.x
  3. activating the environment: conda activate myenv

You need to install matplotlib & numpy

pip or conda install matplotlib

pip or conda install numpy

Then you should be able import this library.
import matplotlib.pyplot as plt


You need a code editor
We recommend to use JupyterLab, a web-based interactive coding application with excution results shown on-fly.
Modern IDE like VsCode, Atom are worth trying.

hello world for matplotlib

let's plot a sine function with Matplotlib:

  • Import numpy package to numerically calculate array and matplotlib to plot.
  • Construct the x and y axis value of the point.
  • Call plot() to draw a line that connects all the points
  • Save the figure and show it on screen
import numpy as np import matplotlib.pyplot as plt x = np.arange(0, 3*np.pi, 0.1) # array for x axis y = np.sin(x) # array for y axis plt.plot(x, y) # plot x vs y plt.savefig('sine.png') # save to file plt.show() # show on screen

hello world for matplotlib

import numpy as np import matplotlib.pyplot as plt x = np.arange(0, 3*np.pi, 0.1) # array for x axis y = np.sin(x) # array for y axis plt.plot(x, y) # plot x vs y plt.savefig('sine.png') # save to file plt.show() # show on screen 🤔Is this figure complete?

hello world for matplotlib

import numpy as np import matplotlib.pyplot as plt x = np.arange(0, 3*np.pi, 0.1) # array for x axis y = np.sin(x) # array for y axis plt.plot(x, y, label = 'sin(x)') plt.xlabel('physical quantity on x axis (unit)') plt.ylabel('physical quantity on y axis (unit)') plt.legend() # create legend plt.savefig('sine.png') # save to file plt.show() # show on screen

Elements of a figure

©️matplotlib cheatsheet

make reader-friendly figure: step 1

  • include at least x,y labels
  • figure resolution (dpi)
  • fontsize

make reader-friendly figure: step 1

No ugly blank border

plt.figure(figsize = (7,5),facecolor= 'yellow') # create a new figure plt.xlabel('physical quantity on x axis (unit)', fontsize = 12) plt.ylabel('physical quantity on y axis (unit)', fontsize = 12) plt.legend(fontsize = 12) # create legend plt.title('title for this figure',fontsize = 15) plt.savefig('sine_highQ.png', dpi = 288, bbox_inches = 'tight')

Line plot: color

You can use 'color' argument to assign the color of the line.

plt.plot(x, y, color = 'r', label = "color = red") plt.plot(x, y+1, color = 'k', label = 'color = \'k\'')

Line plot: linestyle

You can use 'linestyle' argument to change the look of the line.

  • linestyle='-': (default) solid line
  • linestyle='--': dashed line
  • linestyle=':': dotted line
  • linestyle='': do not plot line
plt.plot(x, y, linestyle='--', label="linestyle='--'") plt.plot(x, y+1, linestyle=':', label='linestyle=\':\'') plt.plot(x, y+2, linestyle='', marker='.', label='linestyle=\'\', marker=\'.\'')

Line plot: marker

You can use 'marker' argument to label the data point on the line.

  • marker='.': dot
  • marker='+': +
  • marker='o': larger dot
  • marker='': (default) no marker
  • Try argument 'markersize', 'markeredgecolor', 'markerfacecolor', 'markeredgewidth' yourself!
plt.plot(x, y, color='b', marker='.', label='marker=\'.\'') plt.plot(x, y+1, color='b', marker='+', label='marker=\'+\'') plt.plot(x, y+2, color='b', marker='o', label='marker=\'o\'')

Line plot: linewidth and transparency

  • You can use 'linewidth' argument to adjust the width of the line.
  • You can use 'alpha' argument to adjust the transparency of the line.
plt.plot(x, y, linewidth=4, label='linewidth=4') plt.plot(x, y+1, 'k', label = 'solid black') plt.plot(x, y+1, linewidth=10, alpha = 0.5, label='linewidth=10, alpha=0.5')

Towards the complex: object-oriented class

Let's look at these lines: fig = plt.figure(figsize=(5,4),facecolor= 'white') ax = fig.add_axes([0,0,1,1]) line, = ax.plot(x,y) line.set_color('red') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_title('title') fig.savefig('line_object.png')

note, there is a "," in line, = ax.plot(x,y)

why? ax.plot() returns a list of line objects.


fig, ax, line are respectively objects of figure, axes and line plots.

add_axes(), plot() and set_color() are respectively attributes / functions of these objects.


🤔why object?

review: Elements of a figure

©️matplotlib cheatsheet

Now you can change attributes of every object on this figure!

💡To modify the attribute, you usually use set_?()

subplots

sometimes we want to plot sultiple subfigures in one figure, this is often done by fig.add_subplots() or plt.subplots() . Now we create a figure with 2 times 3 panels:

fig, axes = plt.subplots(2, 3) # create subplot ((ax11, ax12, ax13), (ax21, ax22, ax23)) = axes ax11.plot(x, y) # plot on each axes ax12.plot(x, y+1) ax13.plot(x, y+2) ax21.plot(x, y+3) ax22.plot(x, y+4) ax23.plot(x, y+5)

The line fig, axes = plt.subplots(2, 3) returns a Figure and a 2x3 array of Axes objects

💡You can also use plt.subplots() when you only want to plot one subplot!

share the same axis

Add argument sharey=True to the subplots() so that every subplot share the same y axis property (like range, scale ...)

fig, axes = plt.subplots(2, 3, sharey=True) ((ax11, ax12, ax13), (ax21, ax22, ax23)) = axes ax11.plot(x, y) ax12.plot(x, y+1) ax13.plot(x, y+2) ax21.plot(x, y+3) ax22.plot(x, y+4) ax23.plot(x, y+5)
💡The same can be done to x-axis with sharex=True

subplots of different layout

add argument width_ratios=[the ratio you allocate] / height_ratios to the subplots() to set the width fraction of each subplot.

fig, axes = plt.subplots(2, 3, width_ratios=[1, 2, 3], height_ratios=[2, 1]) ((ax11, ax12, ax13), (ax21, ax22, ax23)) = axes ax11.plot(x, y) ax12.plot(x, y+1) ax13.plot(x, y+2) ax21.plot(x, y+3) ax22.plot(x, y+4) ax23.plot(x, y+5)

💡try plt.subplots_adjust(wsapce =, hspace=,) to adjust the relative position of subplots.

🎯 You are encouraged to investigate more complex layout with functions like G = gridspec(rows,cols,…), ax.inset_axes(extent)... You can find them on the cheatsheet.

a figure with two axis

Sometimes we want to plot 2 quantity with the same invariant in one plot, this can be done with ax.twinx().

fig, ax = plt.subplots(1,1,figsize=(5,4)) ax.plot(x, y) ax.set_ylabel('label for left y axis') ax2 = ax.twinx() ax2.plot(x, -y, color='r', label='plot on right y axis') ax2.tick_params(labelcolor='r', axis='y') # red axis label ax2.set_ylabel('label for right y axis',color='r') plt.legend()
💡And, ax.twiny() is also available

make reader-friendly figure: step2

©️helong

aspect ratio

Aspect ratio determines the length ratio of unit y axis and x axis.

plt.plot(xcircle, ycircle) ax = plt.gca() ax.set_aspect('equal')

Logarithmic axis

sometimes the best scale is not linear

logarithmic axis

ax.set_xscale('log') ax.set_yscale('log')
💡 Here I use ax.annotate() to put descriptions on the plot.

axis range

sometimes you focus on different scales

ax.set_xlim([0, 1]) ax.set_ylim([0, 1])

Beyond line plots

©️matplotlib cheatsheet

read data

You may need this in the homework. You can use readline() to read in .txt file.

with open('solar_system_planet.txt', 'r') as file: # Read the first line to get the headers headers = file.readline().strip().split(',') data = [] for line in file: # Read the rest of the lines for data row_data = line.strip().split(',') # Append the row data to the data list data.append(row_data) print("Headers:", headers) print("Data:", data)
  • split the string at a delimiter: string.split(',')
  • remove something at the beginning or the end: string.strip(' ')
    💡 readline() is useful to skip the lines you don't need.

    💡 Check the dataset for the proper delimiter ("|", "\t", " ")

    💡 This way we read data all as string, you need to transfer them to float.

Use Pandas for .txt/.csv/.xlsx

The library pandas read in data as python dictionary.
You can easily access different quantities by their "position" or "name".

Use Pandas for .txt/.csv/.xlsx

🎯let's try to reproduce the Mass-Radius diagram (data) of solar system objects. import pandas as pd data = pd.read_csv('solar_system_planet.txt',delimiter=',') radius = data['radius'] mass = data['mass'] text = data['object'] fig, ax = plt.subplots(1,1,figsize=(6,4)) ax.scatter(radius,mass,color='tab:blue',s=100,alpha= 0.5) ax.set_xlabel('radius ($R_\oplus$)') ax.set_ylabel('mass ($M_\oplus$)') for i in range(len(text)): if (text[i] == 'Venus') or (text[i] == 'Uranus'): ax.annotate(text[i], (radius[i], mass[i]), textcoords="offset points", xytext=(0,-12), ha='center') else: ax.annotate(text[i], (radius[i], mass[i]), textcoords="offset points", xytext=(0,12), ha='center') ax.set_yscale('log') ax.set_xscale('log')