test_marker.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from matplotlib import markers
  4. from matplotlib.path import Path
  5. from matplotlib.testing.decorators import check_figures_equal
  6. import pytest
  7. def test_markers_valid():
  8. marker_style = markers.MarkerStyle()
  9. mrk_array = np.array([[-0.5, 0],
  10. [0.5, 0]])
  11. # Checking this doesn't fail.
  12. marker_style.set_marker(mrk_array)
  13. def test_markers_invalid():
  14. marker_style = markers.MarkerStyle()
  15. mrk_array = np.array([[-0.5, 0, 1, 2, 3]])
  16. # Checking this does fail.
  17. with pytest.raises(ValueError):
  18. marker_style.set_marker(mrk_array)
  19. def test_marker_path():
  20. marker_style = markers.MarkerStyle()
  21. path = Path([[0, 0], [1, 0]], [Path.MOVETO, Path.LINETO])
  22. # Checking this doesn't fail.
  23. marker_style.set_marker(path)
  24. class UnsnappedMarkerStyle(markers.MarkerStyle):
  25. """
  26. A MarkerStyle where the snap threshold is force-disabled.
  27. This is used to compare to polygon/star/asterisk markers which do not have
  28. any snap threshold set.
  29. """
  30. def _recache(self):
  31. super()._recache()
  32. self._snap_threshold = None
  33. @check_figures_equal()
  34. def test_poly_marker(fig_test, fig_ref):
  35. ax_test = fig_test.add_subplot()
  36. ax_ref = fig_ref.add_subplot()
  37. # Note, some reference sizes must be different because they have unit
  38. # *length*, while polygon markers are inscribed in a circle of unit
  39. # *radius*. This introduces a factor of np.sqrt(2), but since size is
  40. # squared, that becomes 2.
  41. size = 20**2
  42. # Squares
  43. ax_test.scatter([0], [0], marker=(4, 0, 45), s=size)
  44. ax_ref.scatter([0], [0], marker='s', s=size/2)
  45. # Diamonds, with and without rotation argument
  46. ax_test.scatter([1], [1], marker=(4, 0), s=size)
  47. ax_ref.scatter([1], [1], marker=UnsnappedMarkerStyle('D'), s=size/2)
  48. ax_test.scatter([1], [1.5], marker=(4, 0, 0), s=size)
  49. ax_ref.scatter([1], [1.5], marker=UnsnappedMarkerStyle('D'), s=size/2)
  50. # Pentagon, with and without rotation argument
  51. ax_test.scatter([2], [2], marker=(5, 0), s=size)
  52. ax_ref.scatter([2], [2], marker=UnsnappedMarkerStyle('p'), s=size)
  53. ax_test.scatter([2], [2.5], marker=(5, 0, 0), s=size)
  54. ax_ref.scatter([2], [2.5], marker=UnsnappedMarkerStyle('p'), s=size)
  55. # Hexagon, with and without rotation argument
  56. ax_test.scatter([3], [3], marker=(6, 0), s=size)
  57. ax_ref.scatter([3], [3], marker='h', s=size)
  58. ax_test.scatter([3], [3.5], marker=(6, 0, 0), s=size)
  59. ax_ref.scatter([3], [3.5], marker='h', s=size)
  60. # Rotated hexagon
  61. ax_test.scatter([4], [4], marker=(6, 0, 30), s=size)
  62. ax_ref.scatter([4], [4], marker='H', s=size)
  63. # Octagons
  64. ax_test.scatter([5], [5], marker=(8, 0, 22.5), s=size)
  65. ax_ref.scatter([5], [5], marker=UnsnappedMarkerStyle('8'), s=size)
  66. ax_test.set(xlim=(-0.5, 5.5), ylim=(-0.5, 5.5))
  67. ax_ref.set(xlim=(-0.5, 5.5), ylim=(-0.5, 5.5))
  68. def test_star_marker():
  69. # We don't really have a strict equivalent to this marker, so we'll just do
  70. # a smoke test.
  71. size = 20**2
  72. fig, ax = plt.subplots()
  73. ax.scatter([0], [0], marker=(5, 1), s=size)
  74. ax.scatter([1], [1], marker=(5, 1, 0), s=size)
  75. ax.set(xlim=(-0.5, 0.5), ylim=(-0.5, 1.5))
  76. # The asterisk marker is really a star with 0-size inner circle, so the ends
  77. # are corners and get a slight bevel. The reference markers are just singular
  78. # lines without corners, so they have no bevel, and we need to add a slight
  79. # tolerance.
  80. @check_figures_equal(tol=1.45)
  81. def test_asterisk_marker(fig_test, fig_ref, request):
  82. ax_test = fig_test.add_subplot()
  83. ax_ref = fig_ref.add_subplot()
  84. # Note, some reference sizes must be different because they have unit
  85. # *length*, while asterisk markers are inscribed in a circle of unit
  86. # *radius*. This introduces a factor of np.sqrt(2), but since size is
  87. # squared, that becomes 2.
  88. size = 20**2
  89. def draw_ref_marker(y, style, size):
  90. # As noted above, every line is doubled. Due to antialiasing, these
  91. # doubled lines make a slight difference in the .png results.
  92. ax_ref.scatter([y], [y], marker=UnsnappedMarkerStyle(style), s=size)
  93. if request.getfixturevalue('ext') == 'png':
  94. ax_ref.scatter([y], [y], marker=UnsnappedMarkerStyle(style),
  95. s=size)
  96. # Plus
  97. ax_test.scatter([0], [0], marker=(4, 2), s=size)
  98. draw_ref_marker(0, '+', size)
  99. ax_test.scatter([0.5], [0.5], marker=(4, 2, 0), s=size)
  100. draw_ref_marker(0.5, '+', size)
  101. # Cross
  102. ax_test.scatter([1], [1], marker=(4, 2, 45), s=size)
  103. draw_ref_marker(1, 'x', size/2)
  104. ax_test.set(xlim=(-0.5, 1.5), ylim=(-0.5, 1.5))
  105. ax_ref.set(xlim=(-0.5, 1.5), ylim=(-0.5, 1.5))