I have to make plots for several institutions to show their performance against 1 or more receivers. Subplots seemed the correct way to go but it seems each subplot required that I specify the axes parameters even though they are identical. So I created a little piece of code that creates subscripted axes objects and it works UNLESS there is only one receiver.
num_plots = len(receivers)
fig, axes = plt.subplots(num_plots, 1, figsize=(50, 150), squeeze=False)
minor_ticks = md.MinuteLocator(byminute=[0, 15, 30, 45], interval=1)
hours = md.HourLocator(interval=1)
for i,receiver in enumerate(receivers):
axes[i].xaxis.set_minor_locator(minor_ticks)
axes[i].xaxis.set_major_locator(hours)
axes[i].xaxis.set_major_formatter(md.DateFormatter('%H:%M'))
axes[i].xaxis.get_offset_text().set_fontsize(24)
axes[i].yaxis.get_offset_text().set_fontsize(24)
axes[i].grid(b=True, which='major', color='b', linestyle='-', alpha=0.6)
axes[i].grid(b=True, which='minor', color='r', linestyle='--', alpha=0.3)
axes[i].tick_params(axis="both", labelsize=30)
axes[i].set_ylabel('Bilateral Risk/5 min', fontsize=40, weight='bold')
axes[i].set_xlabel('Time', fontsize=40, weight='bold')
If there is only one subplot (basically "fig, axes = plt.subplots(1, 1, fig size(50, 150), squeeze=False)" ) then I get the following error:
Traceback (most recent call last):
.
.
.
File "/Users/xxx/risk_scoring.py", line 276, in plot_result
axes[i].xaxis.set_minor_locator(minor_ticks)
AttributeError: 'numpy.ndarray' object has no attribute 'xaxis'
That's unexpected because I thought from here and here that 'squeeze=' would allow a 1x1 subplot. What is making the error or is there a better way to do this?
FOLLOW UP and ANSWER:
Taking the preceding code and substituting receivers = ["a", "b", "c", "d"] and then same but just one receiver all with 'squeeze=True' (the default):
0
1
2
3
[<matplotlib.axes._subplots.AxesSubplot object at 0x7f865c94b610>
<matplotlib.axes._subplots.AxesSubplot object at 0x7f865b6f3750>
<matplotlib.axes._subplots.AxesSubplot object at 0x7f865b727410>
<matplotlib.axes._subplots.AxesSubplot object at 0x7f865bd67790>]
and
Traceback (most recent call last):
File "main.py", line 186, in <module>
axes[i].xaxis.set_minor_locator(minor_ticks)
TypeError: 'AxesSubplot' object is not subscriptable
And the reason is that 'axes' in the first case is an array but in the second case it is just an object 'AxesSubplot(0.125,0.11;0.775x0.77)'.
If you do the second case (1 receiver) but set 'squeeze=false' you get:
[[<matplotlib.axes._subplots.AxesSubplot object at 0x7f2e447a7790>]]
0
Traceback (most recent call last):
File "main.py", line 186, in <module>
axes[i].xaxis.set_minor_locator(minor_ticks)
AttributeError: 'numpy.ndarray' object has no attribute 'xaxis'
That's a 2-D array. So I changed all references to 'axes' with a 2-D index eg "axes[i][0].set..." and it all seems to work.