diff --git a/doc/api/next_api_changes/behavior/17897-KLP.rst b/doc/api/next_api_changes/behavior/17897-KLP.rst new file mode 100644 index 000000000000..f53534e8d1b9 --- /dev/null +++ b/doc/api/next_api_changes/behavior/17897-KLP.rst @@ -0,0 +1,11 @@ +pyplot.specgram always uses origin='upper' +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Previously if ``image.origin`` was set to something other than 'upper' or if the +``origin`` keyword argument was passed with a value other than 'upper', the spectrogram +itself would flip, but the axes would remain oriented for an origin value of 'upper', so +that the resulting plot was incorrectly labelled. + +Now, the ``origin`` keyword argument is not supported and the ``image.origin`` rcParam is +ignored. The function matplotlib.pyplot.specgram is forced to use ``origin='upper'``, so +that the axes are correct for the plotted spectrogram. diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 40cd2aefa911..4e2c1cab9173 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -7464,7 +7464,8 @@ def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, **kwargs Additional keyword arguments are passed on to `~.axes.Axes.imshow` - which makes the specgram image. + which makes the specgram image. The origin keyword argument + is not supported. Returns ------- @@ -7548,8 +7549,13 @@ def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, xmin, xmax = xextent freqs += Fc extent = xmin, xmax, freqs[0], freqs[-1] + + if 'origin' in kwargs: + raise TypeError("specgram() got an unexpected keyword argument " + "'origin'") + im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax, - **kwargs) + origin='upper', **kwargs) self.axis('auto') return spec, freqs, t, im diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index cbc6a5cdd4a5..791274704d43 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4099,6 +4099,33 @@ def test_specgram_fs_none(): assert xmin == 32 and xmax == 96 +@check_figures_equal(extensions=["png"]) +def test_specgram_origin_rcparam(fig_test, fig_ref): + """Test specgram ignores image.origin rcParam and uses origin 'upper'.""" + t = np.arange(500) + signal = np.sin(t) + + plt.rcParams["image.origin"] = 'upper' + + # Reference: First graph using default origin in imshow (upper), + fig_ref.subplots().specgram(signal) + + # Try to overwrite the setting trying to flip the specgram + plt.rcParams["image.origin"] = 'lower' + + # Test: origin='lower' should be ignored + fig_test.subplots().specgram(signal) + + +def test_specgram_origin_kwarg(): + """Ensure passing origin as a kwarg raises a TypeError.""" + t = np.arange(500) + signal = np.sin(t) + + with pytest.raises(TypeError): + plt.specgram(signal, origin='lower') + + @image_comparison( ["psd_freqs.png", "csd_freqs.png", "psd_noise.png", "csd_noise.png"], remove_text=True, tol=0.002) diff --git a/tutorials/introductory/customizing.py b/tutorials/introductory/customizing.py index 97baedda6427..ab761fb8bcaf 100644 --- a/tutorials/introductory/customizing.py +++ b/tutorials/introductory/customizing.py @@ -12,7 +12,8 @@ ` file (which is read at startup to configure Matplotlib). -There are a number of pre-defined styles `provided by Matplotlib`_. For +There are a number of pre-defined styles :doc:`provided by Matplotlib +`. For example, there's a pre-defined style called "ggplot", which emulates the aesthetics of ggplot_ (a popular plotting package for R_). To use this style, just add: @@ -202,4 +203,3 @@ # # .. _ggplot: https://ggplot2.tidyverse.org/ # .. _R: https://www.r-project.org/ -# .. _provided by Matplotlib: https://github.com/matplotlib/matplotlib/tree/master/lib/matplotlib/mpl-data/stylelib