test_scale.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. from matplotlib.cbook import MatplotlibDeprecationWarning
  2. import matplotlib.pyplot as plt
  3. from matplotlib.scale import (Log10Transform, InvertedLog10Transform,
  4. SymmetricalLogTransform)
  5. from matplotlib.testing.decorators import check_figures_equal, image_comparison
  6. import numpy as np
  7. from numpy.testing import assert_allclose
  8. import io
  9. import platform
  10. import pytest
  11. @check_figures_equal()
  12. def test_log_scales(fig_test, fig_ref):
  13. ax_test = fig_test.add_subplot(122, yscale='log', xscale='symlog')
  14. ax_test.axvline(24.1)
  15. ax_test.axhline(24.1)
  16. xlim = ax_test.get_xlim()
  17. ylim = ax_test.get_ylim()
  18. ax_ref = fig_ref.add_subplot(122, yscale='log', xscale='symlog')
  19. ax_ref.set(xlim=xlim, ylim=ylim)
  20. ax_ref.plot([24.1, 24.1], ylim, 'b')
  21. ax_ref.plot(xlim, [24.1, 24.1], 'b')
  22. def test_symlog_mask_nan():
  23. # Use a transform round-trip to verify that the forward and inverse
  24. # transforms work, and that they respect nans and/or masking.
  25. slt = SymmetricalLogTransform(10, 2, 1)
  26. slti = slt.inverted()
  27. x = np.arange(-1.5, 5, 0.5)
  28. out = slti.transform_non_affine(slt.transform_non_affine(x))
  29. assert_allclose(out, x)
  30. assert type(out) == type(x)
  31. x[4] = np.nan
  32. out = slti.transform_non_affine(slt.transform_non_affine(x))
  33. assert_allclose(out, x)
  34. assert type(out) == type(x)
  35. x = np.ma.array(x)
  36. out = slti.transform_non_affine(slt.transform_non_affine(x))
  37. assert_allclose(out, x)
  38. assert type(out) == type(x)
  39. x[3] = np.ma.masked
  40. out = slti.transform_non_affine(slt.transform_non_affine(x))
  41. assert_allclose(out, x)
  42. assert type(out) == type(x)
  43. @image_comparison(['logit_scales.png'], remove_text=True)
  44. def test_logit_scales():
  45. fig, ax = plt.subplots()
  46. # Typical extinction curve for logit
  47. x = np.array([0.001, 0.003, 0.01, 0.03, 0.1, 0.2, 0.3, 0.4, 0.5,
  48. 0.6, 0.7, 0.8, 0.9, 0.97, 0.99, 0.997, 0.999])
  49. y = 1.0 / x
  50. ax.plot(x, y)
  51. ax.set_xscale('logit')
  52. ax.grid(True)
  53. bbox = ax.get_tightbbox(fig.canvas.get_renderer())
  54. assert np.isfinite(bbox.x0)
  55. assert np.isfinite(bbox.y0)
  56. def test_log_scatter():
  57. """Issue #1799"""
  58. fig, ax = plt.subplots(1)
  59. x = np.arange(10)
  60. y = np.arange(10) - 1
  61. ax.scatter(x, y)
  62. buf = io.BytesIO()
  63. fig.savefig(buf, format='pdf')
  64. buf = io.BytesIO()
  65. fig.savefig(buf, format='eps')
  66. buf = io.BytesIO()
  67. fig.savefig(buf, format='svg')
  68. def test_logscale_subs():
  69. fig, ax = plt.subplots()
  70. ax.set_yscale('log', subsy=np.array([2, 3, 4]))
  71. # force draw
  72. fig.canvas.draw()
  73. @image_comparison(['logscale_mask.png'], remove_text=True)
  74. def test_logscale_mask():
  75. # Check that zero values are masked correctly on log scales.
  76. # See github issue 8045
  77. xs = np.linspace(0, 50, 1001)
  78. fig, ax = plt.subplots()
  79. ax.plot(np.exp(-xs**2))
  80. fig.canvas.draw()
  81. ax.set(yscale="log")
  82. def test_extra_kwargs_raise_or_warn():
  83. fig, ax = plt.subplots()
  84. # with pytest.raises(TypeError):
  85. with pytest.warns(MatplotlibDeprecationWarning):
  86. ax.set_yscale('linear', nonpos='mask')
  87. with pytest.raises(TypeError):
  88. ax.set_yscale('log', nonpos='mask')
  89. # with pytest.raises(TypeError):
  90. with pytest.warns(MatplotlibDeprecationWarning):
  91. ax.set_yscale('symlog', nonpos='mask')
  92. def test_logscale_invert_transform():
  93. fig, ax = plt.subplots()
  94. ax.set_yscale('log')
  95. # get transformation from data to axes
  96. tform = (ax.transAxes + ax.transData.inverted()).inverted()
  97. # direct test of log transform inversion
  98. with pytest.warns(MatplotlibDeprecationWarning):
  99. assert isinstance(Log10Transform().inverted(), InvertedLog10Transform)
  100. def test_logscale_transform_repr():
  101. fig, ax = plt.subplots()
  102. ax.set_yscale('log')
  103. repr(ax.transData) # check that repr of log transform succeeds
  104. # check that repr of log transform succeeds
  105. with pytest.warns(MatplotlibDeprecationWarning):
  106. repr(Log10Transform(nonpos='clip'))
  107. @image_comparison(['logscale_nonpos_values.png'],
  108. remove_text=True, tol=0.02, style='mpl20')
  109. def test_logscale_nonpos_values():
  110. np.random.seed(19680801)
  111. xs = np.random.normal(size=int(1e3))
  112. fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
  113. ax1.hist(xs, range=(-5, 5), bins=10)
  114. ax1.set_yscale('log')
  115. ax2.hist(xs, range=(-5, 5), bins=10)
  116. ax2.set_yscale('log', nonposy='mask')
  117. xdata = np.arange(0, 10, 0.01)
  118. ydata = np.exp(-xdata)
  119. edata = 0.2*(10-xdata)*np.cos(5*xdata)*np.exp(-xdata)
  120. ax3.fill_between(xdata, ydata - edata, ydata + edata)
  121. ax3.set_yscale('log')
  122. x = np.logspace(-1, 1)
  123. y = x ** 3
  124. yerr = x**2
  125. ax4.errorbar(x, y, yerr=yerr)
  126. ax4.set_yscale('log')
  127. ax4.set_xscale('log')
  128. def test_invalid_log_lims():
  129. # Check that invalid log scale limits are ignored
  130. fig, ax = plt.subplots()
  131. ax.scatter(range(0, 4), range(0, 4))
  132. ax.set_xscale('log')
  133. original_xlim = ax.get_xlim()
  134. with pytest.warns(UserWarning):
  135. ax.set_xlim(left=0)
  136. assert ax.get_xlim() == original_xlim
  137. with pytest.warns(UserWarning):
  138. ax.set_xlim(right=-1)
  139. assert ax.get_xlim() == original_xlim
  140. ax.set_yscale('log')
  141. original_ylim = ax.get_ylim()
  142. with pytest.warns(UserWarning):
  143. ax.set_ylim(bottom=0)
  144. assert ax.get_ylim() == original_ylim
  145. with pytest.warns(UserWarning):
  146. ax.set_ylim(top=-1)
  147. assert ax.get_ylim() == original_ylim
  148. @image_comparison(['function_scales.png'], remove_text=True, style='mpl20')
  149. def test_function_scale():
  150. def inverse(x):
  151. return x**2
  152. def forward(x):
  153. return x**(1/2)
  154. fig, ax = plt.subplots()
  155. x = np.arange(1, 1000)
  156. ax.plot(x, x)
  157. ax.set_xscale('function', functions=(forward, inverse))
  158. ax.set_xlim(1, 1000)