In this post, we will learn how to create y-y plots with Python and Matplotlib. Y-y plots are a type of line plot where one line corresponds to one y-axis and another line on the same plot corresponds to a different y-axis. Y-y plots tipically have one vertical y-axis on the left edge of the plot and one vertical y-axis on the right edge of the plot.
We are going to build our y-y plot with Python and Matplotlib. Matplotlib is a popular plotting library for Python. Before we can build the plot, Python needs to be installed on our computer. See [this post] to review how to install Python. I recommend installing the Anaconda distribution of Python, rather than installing Python from Python.org.
Matplotlib can be installed using the Anaconda Prompt or using the command line and pip, the package manager for Python. Matplotlib comes pre-installed with the Anaconda distribution of Python. If you are using the Anaconda distribution of Python, no further installation steps are necessary to use Matplotlib.
Two other libraries we will use to build the plot are NumPy and Jupyter.
Type the command below into the Anaconda Prompt to install Matplotlib, NumPy and Jupyter.
> conda install matplotlib numpy jupyter
The same three libraries can also be installed using a terminal and pip:
$ pip install matplotlib numpy jupyter
We'll use a Jupyter notebook to build the y-y plot. A .py
file could be used as well. The Python code is the same (except for the %matplotlib inline
command). I like using Jupyter notebooks to build plots because of the quick feedback, inline plotting and ability to easily see which plot corresponds to a block of code.
A new Jupyter notebook can be launched from the Anaconda Prompt or a terminal with the command:
> jupyter notebook
In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
The versions of Python, NumPy and Matplotlib can be printed out using the following code:
In [2]:
import matplotlib
import sys
print(f'Python version {sys.version}')
print(f'Matplotlib version {matplotlib.__version__}')
print(f'NumPy version {np.__version__}')
In [3]:
x = np.arange(0,8*np.pi,0.1)
y1 = np.sin(x)
y2 = np.exp(x)
In [4]:
fig, ax = plt.subplots()
ax.plot(x,y1)
ax.set_title('Sin(x)')
plt.show()
We see a plot of the sine function. Note that the y-values in the plot are all between -1
and 1
. We can build a line plot of the exp function using very similar code.
In [5]:
fig, ax = plt.subplots()
ax.plot(x,y2)
ax.set_title('Exp(x)')
plt.show()
We see a plot of the exponential function. Note the y values are between 0
and around 8e10
. The range of y-values in the exp plot is much larger in the exp plot than the sin plot.
Now let's try and plot these two functions on the same set of axes. The code below builds a plot with both functions.
In [6]:
fig, ax = plt.subplots()
ax.plot(x,y1)
ax.plot(x,y2)
ax.set_title('Sin(x) and Exp(x)')
ax.legend(['sin(x)','exp(x)'])
plt.show()
We see a plot with two lines. The blue line represents the sine function and the orange line represents the exp function. Notice how the blue line looks flat, and we can't see the variations in the sine wave.
One way we could view both functions are same time is to use subplots. The code below builds a figure with two subplots, one function in each subplot.
In [7]:
fig, (ax1, ax2) = plt.subplots(nrows=1,ncols=2, figsize=(12,4))
ax1.plot(x,y1)
ax1.set_title('sin(x)')
ax2.plot(x,y2,'C1')
ax2.set_title('exp(x)')
plt.show()
We see two plots side by side each plot shows a different function. The plot on the left is the sine function, the plot on the right is the exp function.
Now let's combine these two plots on the same set of axis, but with a two different y-axes. The y-axis on the left will correspond to the sine function. The y-axis on the right will correspond to the exp function.
In [8]:
fig, ax1 = plt.subplots()
ax1.plot(x,y1)
ax1.set_title('sin(x) and exp(x)')
ax2 = ax1.twinx()
ax2.plot(x,y2,'C1')
plt.show()
We see a plot of two different functions and this time, we can clearly see both the sine function and the exp function.
Next we'll color the axes and the axis labels to correspond to the plot that they go with.
In [9]:
fig, ax1 = plt.subplots()
ax1.plot(x,y1)
ax1.set_ylabel('sin(x)', color='C0')
ax1.tick_params(axis='y', color='C0', labelcolor='C0')
ax1.set_title('sin(x) and exp(x)')
ax2 = ax1.twinx()
ax2.plot(x,y2,'C1')
ax2.set_ylabel('exp(x)', color='C1')
ax2.tick_params(axis='y', color='C1', labelcolor='C1')
ax2.spines['right'].set_color('C1')
ax2.spines['left'].set_color('C0')
plt.show()
In [10]:
fig, ax1 = plt.subplots()
ax1.plot(x,y1)
ax1.set_ylabel('sin(x)', color='C0')
ax1.tick_params(axis='y', color='C0', labelcolor='C0')
ax1.set_title('sin(x) and exp(x)')
ax2 = ax1.twinx()
ax2.plot(x,y2,'C1')
ax2.set_ylabel('exp(x)', color='C1')
ax2.tick_params(axis='y', color='C1', labelcolor='C1')
ax2.spines['right'].set_color('C1')
ax2.spines['left'].set_color('C0')
fig.legend(['sin(x)','exp(x)'], bbox_to_anchor=(0.9, 0.8))
plt.show()