test_arrow_patches.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import pytest
  2. import platform
  3. import matplotlib.pyplot as plt
  4. from matplotlib.testing.decorators import image_comparison
  5. import matplotlib.patches as mpatches
  6. def draw_arrow(ax, t, r):
  7. ax.annotate('', xy=(0.5, 0.5 + r), xytext=(0.5, 0.5), size=30,
  8. arrowprops=dict(arrowstyle=t,
  9. fc="b", ec='k'))
  10. @image_comparison(['fancyarrow_test_image'])
  11. def test_fancyarrow():
  12. # Added 0 to test division by zero error described in issue 3930
  13. r = [0.4, 0.3, 0.2, 0.1, 0]
  14. t = ["fancy", "simple", mpatches.ArrowStyle.Fancy()]
  15. fig, axs = plt.subplots(len(t), len(r), squeeze=False,
  16. figsize=(8, 4.5), subplot_kw=dict(aspect=1))
  17. for i_r, r1 in enumerate(r):
  18. for i_t, t1 in enumerate(t):
  19. ax = axs[i_t, i_r]
  20. draw_arrow(ax, t1, r1)
  21. ax.tick_params(labelleft=False, labelbottom=False)
  22. @image_comparison(['boxarrow_test_image.png'])
  23. def test_boxarrow():
  24. styles = mpatches.BoxStyle.get_styles()
  25. n = len(styles)
  26. spacing = 1.2
  27. figheight = (n * spacing + .5)
  28. fig = plt.figure(figsize=(4 / 1.5, figheight / 1.5))
  29. fontsize = 0.3 * 72
  30. for i, stylename in enumerate(sorted(styles)):
  31. fig.text(0.5, ((n - i) * spacing - 0.5)/figheight, stylename,
  32. ha="center",
  33. size=fontsize,
  34. transform=fig.transFigure,
  35. bbox=dict(boxstyle=stylename, fc="w", ec="k"))
  36. def __prepare_fancyarrow_dpi_cor_test():
  37. """
  38. Convenience function that prepares and returns a FancyArrowPatch. It aims
  39. at being used to test that the size of the arrow head does not depend on
  40. the DPI value of the exported picture.
  41. NB: this function *is not* a test in itself!
  42. """
  43. fig2 = plt.figure("fancyarrow_dpi_cor_test", figsize=(4, 3), dpi=50)
  44. ax = fig2.add_subplot(111)
  45. ax.set_xlim([0, 1])
  46. ax.set_ylim([0, 1])
  47. ax.add_patch(mpatches.FancyArrowPatch(posA=(0.3, 0.4), posB=(0.8, 0.6),
  48. lw=3, arrowstyle='->',
  49. mutation_scale=100))
  50. return fig2
  51. @image_comparison(['fancyarrow_dpi_cor_100dpi.png'], remove_text=True,
  52. tol={'aarch64': 0.02}.get(platform.machine(), 0.0),
  53. savefig_kwarg=dict(dpi=100))
  54. def test_fancyarrow_dpi_cor_100dpi():
  55. """
  56. Check the export of a FancyArrowPatch @ 100 DPI. FancyArrowPatch is
  57. instantiated through a dedicated function because another similar test
  58. checks a similar export but with a different DPI value.
  59. Remark: test only a rasterized format.
  60. """
  61. __prepare_fancyarrow_dpi_cor_test()
  62. @image_comparison(['fancyarrow_dpi_cor_200dpi.png'], remove_text=True,
  63. tol={'aarch64': 0.02}.get(platform.machine(), 0.0),
  64. savefig_kwarg=dict(dpi=200))
  65. def test_fancyarrow_dpi_cor_200dpi():
  66. """
  67. As test_fancyarrow_dpi_cor_100dpi, but exports @ 200 DPI. The relative size
  68. of the arrow head should be the same.
  69. """
  70. __prepare_fancyarrow_dpi_cor_test()
  71. @image_comparison(['fancyarrow_dash.png'], remove_text=True, style='default')
  72. def test_fancyarrow_dash():
  73. from matplotlib.patches import FancyArrowPatch
  74. fig, ax = plt.subplots()
  75. e = FancyArrowPatch((0, 0), (0.5, 0.5),
  76. arrowstyle='-|>',
  77. connectionstyle='angle3,angleA=0,angleB=90',
  78. mutation_scale=10.0,
  79. linewidth=2,
  80. linestyle='dashed',
  81. color='k')
  82. e2 = FancyArrowPatch((0, 0), (0.5, 0.5),
  83. arrowstyle='-|>',
  84. connectionstyle='angle3',
  85. mutation_scale=10.0,
  86. linewidth=2,
  87. linestyle='dotted',
  88. color='k')
  89. ax.add_patch(e)
  90. ax.add_patch(e2)
  91. @image_comparison(['arrow_styles.png'], style='mpl20', remove_text=True)
  92. def test_arrow_styles():
  93. styles = mpatches.ArrowStyle.get_styles()
  94. n = len(styles)
  95. fig, ax = plt.subplots(figsize=(6, 10))
  96. ax.set_xlim(0, 1)
  97. ax.set_ylim(-1, n)
  98. for i, stylename in enumerate(sorted(styles)):
  99. patch = mpatches.FancyArrowPatch((0.1, i), (0.8, i),
  100. arrowstyle=stylename,
  101. mutation_scale=25)
  102. ax.add_patch(patch)
  103. @image_comparison(['connection_styles.png'], style='mpl20', remove_text=True)
  104. def test_connection_styles():
  105. styles = mpatches.ConnectionStyle.get_styles()
  106. n = len(styles)
  107. fig, ax = plt.subplots(figsize=(6, 10))
  108. ax.set_xlim(0, 1)
  109. ax.set_ylim(-1, n)
  110. for i, stylename in enumerate(sorted(styles)):
  111. patch = mpatches.FancyArrowPatch((0.1, i), (0.8, i + 0.5),
  112. arrowstyle="->",
  113. connectionstyle=stylename,
  114. mutation_scale=25)
  115. ax.add_patch(patch)
  116. def test_invalid_intersection():
  117. conn_style_1 = mpatches.ConnectionStyle.Angle3(angleA=20, angleB=200)
  118. p1 = mpatches.FancyArrowPatch((.2, .2), (.5, .5),
  119. connectionstyle=conn_style_1)
  120. with pytest.raises(ValueError):
  121. plt.gca().add_patch(p1)
  122. conn_style_2 = mpatches.ConnectionStyle.Angle3(angleA=20, angleB=199.9)
  123. p2 = mpatches.FancyArrowPatch((.2, .2), (.5, .5),
  124. connectionstyle=conn_style_2)
  125. plt.gca().add_patch(p2)