<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Today we'll be using matplotlib's pyplot to make clearer, prettier figures.
First we import packages and generate some data to plot.
Step1:  Pump up the font sizes on plots. Better to do it now than when you need 10 plots for a powerpoint!
Step2:  More fine grained control can be exerted with  rc from matplotlib
Step3:  Make 9 sine curves with random offsets and noise.
Step4:  Now plot all of them
Step5:  What a mess! Better off with some subplots
Step6:  We can improve this by sharing axis labels and reducing the space between plots
Step7:  Subplots don't have to be identical. If we want we can change the relative sizes with gridspec. Especailly useful if you are mixing line and contour plots into one superfigure
Step8:  Some more tricks to make the plot look better
Step9:  We can use this method to make split level plots, if for instance you want to capture near surface variability in greater detail
Step10:  A few more examples can be found in this post
<ASSISTANT_TASK:>
Python Code:
import numpy as np
import matplotlib.pyplot as plt
Explanation: Today we'll be using matplotlib's pyplot to make clearer, prettier figures.
First we import packages and generate some data to plot.
End of explanation
plt.rcParams.update({"font.size": 20})
Explanation: Pump up the font sizes on plots. Better to do it now than when you need 10 plots for a powerpoint!
End of explanation
SMALL_SIZE = 16
MED_SIZE = 20
LARGE_SIZE = 26
plt.rc('font', size=MED_SIZE)
plt.rc('xtick', labelsize=SMALL_SIZE)
plt.rc('ytick', labelsize=SMALL_SIZE)
plt.rc('axes', titlesize=MED_SIZE)
plt.rc('legend', fontsize=MED_SIZE)
Explanation: More fine grained control can be exerted with  rc from matplotlib
End of explanation
time = np.linspace(0, np.pi, 50)
no_of_lines = 9
x1 = np.empty((no_of_lines, len(time)))
for row in range(no_of_lines):
    x1[row, :] = np.sin(time + 2 * np.pi * np.random.rand()) + 0.2 * np.random.rand(len(time))
plt.plot(time, x1[0, :])
Explanation: Make 9 sine curves with random offsets and noise.
End of explanation
for row in range(no_of_lines):
    plt.plot(time, x1[row, :])
Explanation: Now plot all of them
End of explanation
# Using subplots to make a 3 X 3 grid of axes for plotting
fig, axs = plt.subplots(3, 3, figsize=(8, 8))
# ravel makes the axs object into an array of 9 objects we can access
# with indices, very handy for plotting within a loop
axs = axs.ravel()
for row in range(no_of_lines):
    axs[row].plot(time, x1[row, :])
Explanation: What a mess! Better off with some subplots
End of explanation
fig, axs = plt.subplots(3, 3, figsize=(8, 8), sharex="col", sharey="row")
axs = axs.ravel()
fig.subplots_adjust(hspace=0.05, wspace=0.05)
for row in range(no_of_lines):
    axs[row].plot(time, x1[row, :]);
Explanation: We can improve this by sharing axis labels and reducing the space between plots
End of explanation
# Making a grid of temperature data with meshgrid
delta1 = 0.025
x1 = np.sin(np.arange(np.pi / 4, 3 * np.pi / 4, delta1))
y1 = np.arange(10, 20, delta1)
X1, Y1 = np.meshgrid(x1, y1)
temp = X1 * Y1
distance = np.linspace(0, 90, len(x1))
depth = 20 - y1
fig, axs = plt.subplots(
    2,
    2,
    figsize=(8, 8),
    sharex="col",
    sharey="row",
    gridspec_kw={"height_ratios": [1, 4], "width_ratios": [4, 1]},
)
fig.subplots_adjust(hspace=0, wspace=0)
axs = axs.ravel()
# Plotting the surface temperature and mean temp depth profile alongside the contour plot of temp
axs[0].plot(distance, temp[-1, :], label="surface temp")
axs[2].contourf(distance, depth, temp)
axs[3].plot(np.nanmean(temp, 1), depth)
# Setting limits to keep things tight
axs[2].set(xlim=[distance[0], distance[-1]], ylim=[depth[0], depth[-1]])
axs[3].set(xlim=[np.min(temp), np.max(temp)]);
Explanation: Subplots don't have to be identical. If we want we can change the relative sizes with gridspec. Especailly useful if you are mixing line and contour plots into one superfigure
End of explanation
fig, axs = plt.subplots(2, 2, figsize=(8, 8), sharex="col", sharey="row",
                        gridspec_kw={"height_ratios": [1, 4], "width_ratios": [4, 1]})
fig.subplots_adjust(hspace=0, wspace=0)
axs = axs.ravel()
axs[0].plot(distance, temp[-1, :], label="surface temp")
p1 = axs[2].contourf(distance, depth, temp)
axs[3].plot(np.nanmean(temp, 1), depth)
# Add a colorbar to the right of the bottom right plot
fig.colorbar(ax=axs[3], mappable=p1, label=r"Temperature $\mathrm{^{\circ}C}$")
# Add a label to the first subplot
axs[0].legend()
# Remove the lines and ticks from the unused top right axis
axs[1].axis("off")
# Addding labels and limits
axs[2].set(
    xlim=[distance[0], distance[-1]],
    ylim=[depth[0], depth[-1]],
    ylabel="Depth (m)",
    xlabel="Distance (km)",
)
axs[3].set(xlim=[np.min(temp), np.max(temp)], xlabel="mean temp");
Explanation: Some more tricks to make the plot look better
End of explanation
fig,axs = plt.subplots(2,1,figsize=(8,8),sharex = 'col',
                      gridspec_kw = {'height_ratios':[1, 2]})
fig.subplots_adjust(hspace = 0, wspace=0)
axs = axs.ravel()
split_level = 0.1
# Plotting the surface temperature and mean temp depth profile alongside the contour plot of temp
axs[0].contourf(distance,depth,temp)
axs[0].set(ylim=[split_level,depth[-1]])
axs[1].contourf(distance,depth,temp)
axs[1].set(ylim=[depth[0],split_level])
# Setting limits to keep things tight
axs[1].set(xlim=[distance[0],distance[-1]])
Explanation: We can use this method to make split level plots, if for instance you want to capture near surface variability in greater detail
End of explanation
HTML(html)
Explanation: A few more examples can be found in this post: More on subplots in matplotlib.
End of explanation
<END_TASK>