Here in this article, I am trying to explain the process of creating inset pictures within Python plots. In many cases of data visualization, we need to make the best use of available space for plots. In my experience, each plot is unique in its own way so that few improvements here and there makes it visually more pleasing and we will be able to convey more information using minimum space. Here I am plotting Energy Decay Curve of an audio signal (wav file) with its time domain view in inset.
Before proceeding further lets take a look at how the plot will look in the end.
The first step would be to import the necessary libraries.
import numpy as np import matplotlib.pyplot as plt from scipy.io import wavfile
One of the important parts is to know the dimension (or at least the aspect ratio) of the image you want. I usually take the Golden ratio (1.61) as the aspect ratio. You need to decide the font size also according to the dimension so that labels wont look too big or too small.
width = 3.5 height = width / 1.618 labelsize = 10 legendfont = 8 lwidth = 0.8 plt.rc('pdf', fonttype = 42) plt.rc('font', family = 'serif') plt.rc('text', usetex = True) plt.rc('xtick', labelsize = labelsize) plt.rc('ytick', labelsize = labelsize) plt.rc('axes', labelsize = labelsize)
The following code generates the data to be plotted.
inputfile = 'IRTrimmed.wav' Fs, x = wavfile.read(inputfile) Fs = float(Fs) rangetoplot = 2000 Lp = len(x) Tp = np.arange(0, Lp / Fs, (1 / Fs)).T Ppower = np.square(x) PpowerRev = Ppower[::-1] PEnergy = np.cumsum(PpowerRev)[::-1] PEdB = 10 * np.log10(PEnergy)
Next, we create a figure object.
fig1, ax = plt.subplots() fig1.subplots_adjust(left=0.16, bottom=0.2, right=0.99, top=0.97)
Now we can plot the main data and label the axes and legend.
plt.plot(Tp, PEdB, ls="solid", color="b", label="Energy decay curve", linewidth=lwidth) plt.grid(True, which="both", linestyle=":", linewidth=0.6) plt.xlabel("Time(sec)") plt.ylabel("Energy(dB)") plt.legend(loc="upper right", fontsize=legendfont)
Then we can create an inset inside our main plot and add a graph there.
ax2 = fig1.add_axes([0.25, 0.25, 0.4, 0.4]) ax2.plot( Tp[0:rangetoplot], x[0:rangetoplot], ls="solid", color="k", linewidth=0.5, label="RIR Time Domain", ) ax2.set_xticks() ax2.set_yticks()
Finally, we can save the plot to a dimension we want.
fig1.set_size_inches(width, height) fig1.savefig("EnergyRIR.png", dpi=600)
By tweaking the default setting of plots it is possible to create publication-quality plots. Inset plotting can help save more space and convey more information when it comes to journal publications where there is often a page limit.