Thanks, I could reproduce this now. I could make it work by passing show=False and showing the figure manually after updating the axis titles.
import os
import matplotlib.pyplot as plt
import mne
sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(sample_data_folder, 'MEG', 'sample',
'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(sample_data_raw_file, verbose=False)
fig, ax = plt.subplots(3) # In this example dataset, we have 3 channel types -> 3 axes required!
raw.plot_psd(ax=ax, show=False)
ax[0].set_title('foo')
ax[1].set_title('bar')
ax[2].set_title('baz')
fig.tight_layout() # Without this, I got ugly overlaps between titles and plots!
fig.show()