I have a question about an error I receive when looping to plot multiple subplots from a data frame.
My data frame has many columns, of which I loop over to have a subplot of each column.
This is my code
def plot(df):
channels=[]
for i in df:
channels.append(i)
fig, ax = plt.subplots(len(channels), sharex=True, figsize=(50,100))
plot=0
for j in df:
ax[plot].plot(df["%s" % j])
ax[plot].set_xlabel('%s' % j)
plot=plot+1
plt.tight_layout()
plt.show()
I get the plot produced fine, but also an empty frame and the error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\AClayton\WinPython-64bit-2.7.5.3\python-2.7.5.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 538, in runfile
execfile(filename, namespace)
File "C:/Users/AClayton/Desktop/Data/TS.py", line 67, in <module>
plot(all_data)
File "C:/Users/AClayton/Desktop/Data/TS.py", line 49, in plot
ax[plot].plot(reader["%s" % j])
TypeError: 'AxesSubplot' object does not support indexing
I can't see where this error comes from if the first plot is produced fine, or why the second figure is produced?
Thanks for any insight
If you plot multiple subplots, the plt.subplots()
returns the axes in an array, that array allows indexing like you do with ax[plot]
. When only 1 subplot is created, by default it returns the axes itself, not the axes within an array.
So your error occurs when len(channels)
equals 1. You can suppress this behavior by setting squeeze=False
in the .subplots()
command. This forces it to always return a 'Rows x Cols' sized array with the axes, even if its a single one.
So:
def plot(df):
channels=[]
for i in df:
channels.append(i)
fig, ax = plt.subplots(len(channels),1, sharex=True, figsize=(50,100), squeeze=False)
plot=0
for j in df:
ax[plot,0].plot(df["%s" % j])
ax[plot,0].set_xlabel('%s' % j)
plot=plot+1
plt.tight_layout()
plt.show()
By adding the squeeze
keyword you always get a 2D array in return, so the indexing for a subplot changes to ax[plot,0]
. I have also specifically added the amount of columns (1 in this case).