@@ -140,6 +140,25 @@ def test_label_shift():
140
140
assert ax .yaxis .get_label ().get_horizontalalignment () == "center"
141
141
142
142
143
+ @check_figures_equal (extensions = ["png" ])
144
+ def test_acorr (fig_test , fig_ref ):
145
+ np .random .seed (19680801 )
146
+ Nx = 512
147
+ x = np .random .normal (0 , 1 , Nx ).cumsum ()
148
+ maxlags = Nx - 1
149
+
150
+ ax_test = fig_test .subplots ()
151
+ ax_test .acorr (x , maxlags = maxlags )
152
+
153
+ ax_ref = fig_ref .subplots ()
154
+ # Normalized autocorrelation
155
+ norm_auto_corr = np .correlate (x , x , mode = "full" )/ np .dot (x , x )
156
+ lags = np .arange (- maxlags , maxlags + 1 )
157
+ norm_auto_corr = norm_auto_corr [Nx - 1 - maxlags :Nx + maxlags ]
158
+ ax_ref .vlines (lags , [0 ], norm_auto_corr )
159
+ ax_ref .axhline (y = 0 , xmin = 0 , xmax = 1 )
160
+
161
+
143
162
@check_figures_equal (extensions = ["png" ])
144
163
def test_spy (fig_test , fig_ref ):
145
164
np .random .seed (19680801 )
@@ -4706,6 +4725,253 @@ def test_subplot_key_hash():
4706
4725
assert ax .get_subplotspec ().get_geometry () == (5 , 1 , 0 , 0 )
4707
4726
4708
4727
4728
+ @pytest .mark .filterwarnings (
4729
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4730
+ @image_comparison (
4731
+ ["specgram_freqs.png" , "specgram_freqs_linear.png" ,
4732
+ "specgram_noise.png" , "specgram_noise_linear.png" ],
4733
+ remove_text = True , tol = 0.07 , style = "default" )
4734
+ def test_specgram ():
4735
+ """Test axes.specgram in default (psd) mode."""
4736
+
4737
+ # use former defaults to match existing baseline image
4738
+ matplotlib .rcParams ['image.interpolation' ] = 'nearest'
4739
+
4740
+ n = 1000
4741
+ Fs = 10.
4742
+
4743
+ fstims = [[Fs / 4 , Fs / 5 , Fs / 11 ], [Fs / 4.7 , Fs / 5.6 , Fs / 11.9 ]]
4744
+ NFFT_freqs = int (10 * Fs / np .min (fstims ))
4745
+ x = np .arange (0 , n , 1 / Fs )
4746
+ y_freqs = np .concatenate (
4747
+ np .sin (2 * np .pi * np .multiply .outer (fstims , x )).sum (axis = 1 ))
4748
+
4749
+ NFFT_noise = int (10 * Fs / 11 )
4750
+ np .random .seed (0 )
4751
+ y_noise = np .concatenate ([np .random .standard_normal (n ), np .random .rand (n )])
4752
+
4753
+ all_sides = ["default" , "onesided" , "twosided" ]
4754
+ for y , NFFT in [(y_freqs , NFFT_freqs ), (y_noise , NFFT_noise )]:
4755
+ noverlap = NFFT // 2
4756
+ pad_to = int (2 ** np .ceil (np .log2 (NFFT )))
4757
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4758
+ ax .specgram (y , NFFT = NFFT , Fs = Fs , noverlap = noverlap ,
4759
+ pad_to = pad_to , sides = sides )
4760
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4761
+ ax .specgram (y , NFFT = NFFT , Fs = Fs , noverlap = noverlap ,
4762
+ pad_to = pad_to , sides = sides ,
4763
+ scale = "linear" , norm = matplotlib .colors .LogNorm ())
4764
+
4765
+ @pytest .mark .filterwarnings (
4766
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4767
+ @image_comparison (
4768
+ ["specgram_magnitude_freqs.png" , "specgram_magnitude_freqs_linear.png" ,
4769
+ "specgram_magnitude_noise.png" , "specgram_magnitude_noise_linear.png" ],
4770
+ remove_text = True , tol = 0.07 , style = "default" )
4771
+ def test_specgram_magnitude ():
4772
+ """Test axes.specgram in magnitude mode."""
4773
+
4774
+ # use former defaults to match existing baseline image
4775
+ matplotlib .rcParams ['image.interpolation' ] = 'nearest'
4776
+
4777
+ n = 1000
4778
+ Fs = 10.
4779
+
4780
+ fstims = [[Fs / 4 , Fs / 5 , Fs / 11 ], [Fs / 4.7 , Fs / 5.6 , Fs / 11.9 ]]
4781
+ NFFT_freqs = int (100 * Fs / np .min (fstims ))
4782
+ x = np .arange (0 , n , 1 / Fs )
4783
+ y = np .sin (2 * np .pi * np .multiply .outer (fstims , x )).sum (axis = 1 )
4784
+ y [:, - 1 ] = 1
4785
+ y_freqs = np .hstack (y )
4786
+
4787
+ NFFT_noise = int (10 * Fs / 11 )
4788
+ np .random .seed (0 )
4789
+ y_noise = np .concatenate ([np .random .standard_normal (n ), np .random .rand (n )])
4790
+
4791
+ all_sides = ["default" , "onesided" , "twosided" ]
4792
+ for y , NFFT in [(y_freqs , NFFT_freqs ), (y_noise , NFFT_noise )]:
4793
+ noverlap = NFFT // 2
4794
+ pad_to = int (2 ** np .ceil (np .log2 (NFFT )))
4795
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4796
+ ax .specgram (y , NFFT = NFFT , Fs = Fs , noverlap = noverlap ,
4797
+ pad_to = pad_to , sides = sides , mode = "magnitude" )
4798
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4799
+ ax .specgram (y , NFFT = NFFT , Fs = Fs , noverlap = noverlap ,
4800
+ pad_to = pad_to , sides = sides , mode = "magnitude" ,
4801
+ scale = "linear" , norm = matplotlib .colors .LogNorm ())
4802
+
4803
+
4804
+ @pytest .mark .filterwarnings (
4805
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4806
+ @image_comparison (
4807
+ ["specgram_angle_freqs.png" , "specgram_phase_freqs.png" ,
4808
+ "specgram_angle_noise.png" , "specgram_phase_noise.png" ],
4809
+ remove_text = True , tol = 0.07 , style = "default" )
4810
+ def test_specgram_angle ():
4811
+ """Test axes.specgram in angle and phase modes."""
4812
+
4813
+ # use former defaults to match existing baseline image
4814
+ matplotlib .rcParams ['image.interpolation' ] = 'nearest'
4815
+
4816
+ n = 1000
4817
+ Fs = 10.
4818
+
4819
+ fstims = [[Fs / 4 , Fs / 5 , Fs / 11 ], [Fs / 4.7 , Fs / 5.6 , Fs / 11.9 ]]
4820
+ NFFT_freqs = int (10 * Fs / np .min (fstims ))
4821
+ x = np .arange (0 , n , 1 / Fs )
4822
+ y = np .sin (2 * np .pi * np .multiply .outer (fstims , x )).sum (axis = 1 )
4823
+ y [:, - 1 ] = 1
4824
+ y_freqs = np .hstack (y )
4825
+
4826
+ NFFT_noise = int (10 * Fs / 11 )
4827
+ np .random .seed (0 )
4828
+ y_noise = np .concatenate ([np .random .standard_normal (n ), np .random .rand (n )])
4829
+
4830
+ all_sides = ["default" , "onesided" , "twosided" ]
4831
+ for y , NFFT in [(y_freqs , NFFT_freqs ), (y_noise , NFFT_noise )]:
4832
+ noverlap = NFFT // 2
4833
+ pad_to = int (2 ** np .ceil (np .log2 (NFFT )))
4834
+ for mode in ["angle" , "phase" ]:
4835
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4836
+ ax .specgram (y , NFFT = NFFT , Fs = Fs , noverlap = noverlap ,
4837
+ pad_to = pad_to , sides = sides , mode = mode )
4838
+ with pytest .raises (ValueError ):
4839
+ ax .specgram (y , NFFT = NFFT , Fs = Fs , noverlap = noverlap ,
4840
+ pad_to = pad_to , sides = sides , mode = mode ,
4841
+ scale = "dB" )
4842
+
4843
+
4844
+ @pytest .mark .filterwarnings (
4845
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4846
+ def test_specgram_fs_none ():
4847
+ """Test axes.specgram when Fs is None, should not throw error."""
4848
+ spec , freqs , t , im = plt .specgram (np .ones (300 ), Fs = None , scale = 'linear' )
4849
+ xmin , xmax , freq0 , freq1 = im .get_extent ()
4850
+ assert xmin == 32 and xmax == 96
4851
+
4852
+
4853
+ @pytest .mark .filterwarnings (
4854
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4855
+ @check_figures_equal (extensions = ["png" ])
4856
+ def test_specgram_origin_rcparam (fig_test , fig_ref ):
4857
+ """Test specgram ignores image.origin rcParam and uses origin 'upper'."""
4858
+ t = np .arange (500 )
4859
+ signal = np .sin (t )
4860
+
4861
+ plt .rcParams ["image.origin" ] = 'upper'
4862
+
4863
+ # Reference: First graph using default origin in imshow (upper),
4864
+ fig_ref .subplots ().specgram (signal )
4865
+
4866
+ # Try to overwrite the setting trying to flip the specgram
4867
+ plt .rcParams ["image.origin" ] = 'lower'
4868
+
4869
+ # Test: origin='lower' should be ignored
4870
+ fig_test .subplots ().specgram (signal )
4871
+
4872
+
4873
+ @pytest .mark .filterwarnings (
4874
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4875
+ def test_specgram_origin_kwarg ():
4876
+ """Ensure passing origin as a kwarg raises a TypeError."""
4877
+ t = np .arange (500 )
4878
+ signal = np .sin (t )
4879
+
4880
+ with pytest .raises (TypeError ):
4881
+ plt .specgram (signal , origin = 'lower' )
4882
+
4883
+ @pytest .mark .filterwarnings (
4884
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4885
+ @image_comparison (
4886
+ ["psd_freqs.png" , "csd_freqs.png" , "psd_noise.png" , "csd_noise.png" ],
4887
+ remove_text = True , tol = 0.002 )
4888
+ def test_psd_csd ():
4889
+ n = 10000
4890
+ Fs = 100.
4891
+
4892
+ fstims = [[Fs / 4 , Fs / 5 , Fs / 11 ], [Fs / 4.7 , Fs / 5.6 , Fs / 11.9 ]]
4893
+ NFFT_freqs = int (1000 * Fs / np .min (fstims ))
4894
+ x = np .arange (0 , n , 1 / Fs )
4895
+ ys_freqs = np .sin (2 * np .pi * np .multiply .outer (fstims , x )).sum (axis = 1 )
4896
+
4897
+ NFFT_noise = int (1000 * Fs / 11 )
4898
+ np .random .seed (0 )
4899
+ ys_noise = [np .random .standard_normal (n ), np .random .rand (n )]
4900
+
4901
+ all_kwargs = [{"sides" : "default" },
4902
+ {"sides" : "onesided" , "return_line" : False },
4903
+ {"sides" : "twosided" , "return_line" : True }]
4904
+ for ys , NFFT in [(ys_freqs , NFFT_freqs ), (ys_noise , NFFT_noise )]:
4905
+ noverlap = NFFT // 2
4906
+ pad_to = int (2 ** np .ceil (np .log2 (NFFT )))
4907
+ for ax , kwargs in zip (plt .figure ().subplots (3 ), all_kwargs ):
4908
+ ret = ax .psd (np .concatenate (ys ), NFFT = NFFT , Fs = Fs ,
4909
+ noverlap = noverlap , pad_to = pad_to , ** kwargs )
4910
+ assert len (ret ) == 2 + kwargs .get ("return_line" , False )
4911
+ ax .set (xlabel = "" , ylabel = "" )
4912
+ for ax , kwargs in zip (plt .figure ().subplots (3 ), all_kwargs ):
4913
+ ret = ax .csd (* ys , NFFT = NFFT , Fs = Fs ,
4914
+ noverlap = noverlap , pad_to = pad_to , ** kwargs )
4915
+ assert len (ret ) == 2 + kwargs .get ("return_line" , False )
4916
+ ax .set (xlabel = "" , ylabel = "" )
4917
+
4918
+
4919
+ @pytest .mark .filterwarnings (
4920
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4921
+ @image_comparison (
4922
+ ["magnitude_spectrum_freqs_linear.png" ,
4923
+ "magnitude_spectrum_freqs_dB.png" ,
4924
+ "angle_spectrum_freqs.png" ,
4925
+ "phase_spectrum_freqs.png" ,
4926
+ "magnitude_spectrum_noise_linear.png" ,
4927
+ "magnitude_spectrum_noise_dB.png" ,
4928
+ "angle_spectrum_noise.png" ,
4929
+ "phase_spectrum_noise.png" ],
4930
+ remove_text = True )
4931
+ def test_spectrum ():
4932
+ n = 10000
4933
+ Fs = 100.
4934
+
4935
+ fstims1 = [Fs / 4 , Fs / 5 , Fs / 11 ]
4936
+ NFFT = int (1000 * Fs / min (fstims1 ))
4937
+ pad_to = int (2 ** np .ceil (np .log2 (NFFT )))
4938
+
4939
+ x = np .arange (0 , n , 1 / Fs )
4940
+ y_freqs = ((np .sin (2 * np .pi * np .outer (x , fstims1 )) * 10 ** np .arange (3 ))
4941
+ .sum (axis = 1 ))
4942
+ np .random .seed (0 )
4943
+ y_noise = np .hstack ([np .random .standard_normal (n ), np .random .rand (n )]) - .5
4944
+
4945
+ all_sides = ["default" , "onesided" , "twosided" ]
4946
+ kwargs = {"Fs" : Fs , "pad_to" : pad_to }
4947
+ for y in [y_freqs , y_noise ]:
4948
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4949
+ spec , freqs , line = ax .magnitude_spectrum (y , sides = sides , ** kwargs )
4950
+ ax .set (xlabel = "" , ylabel = "" )
4951
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4952
+ spec , freqs , line = ax .magnitude_spectrum (y , sides = sides , ** kwargs ,
4953
+ scale = "dB" )
4954
+ ax .set (xlabel = "" , ylabel = "" )
4955
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4956
+ spec , freqs , line = ax .angle_spectrum (y , sides = sides , ** kwargs )
4957
+ ax .set (xlabel = "" , ylabel = "" )
4958
+ for ax , sides in zip (plt .figure ().subplots (3 ), all_sides ):
4959
+ spec , freqs , line = ax .phase_spectrum (y , sides = sides , ** kwargs )
4960
+ ax .set (xlabel = "" , ylabel = "" )
4961
+
4962
+
4963
+ @pytest .mark .filterwarnings (
4964
+ 'ignore::matplotlib._api.deprecation.MatplotlibDeprecationWarning' )
4965
+ def test_psd_csd_edge_cases ():
4966
+ # Inverted yaxis or fully zero inputs used to throw exceptions.
4967
+ axs = plt .figure ().subplots (2 )
4968
+ for ax in axs :
4969
+ ax .yaxis .set (inverted = True )
4970
+ with np .errstate (divide = "ignore" ):
4971
+ axs [0 ].psd (np .zeros (5 ))
4972
+ axs [1 ].csd (np .zeros (5 ), np .zeros (5 ))
4973
+
4974
+
4709
4975
@check_figures_equal (extensions = ['png' ])
4710
4976
def test_twin_remove (fig_test , fig_ref ):
4711
4977
ax_test = fig_test .add_subplot ()
0 commit comments