From 25fce22398778c64fc15ab5832ce5ab71dec418f Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 20 Aug 2022 20:34:38 -0400 Subject: [PATCH 1/2] Make imports in tests implicit Not only has `pylab` been discouraged for a long long time, but using explicit API means there's no need to avoid deprecation warnings (which means you won't miss other deprecation warnings, such as the one saying the import you're using to ignore deprecation warnings was itself deprecated.) --- tests/region_label_visual.ipynb | 39 ++++++++++----- tests/region_visual.ipynb | 86 +++++++++++++++++++-------------- tests/utils.py | 10 +--- 3 files changed, 76 insertions(+), 59 deletions(-) diff --git a/tests/region_label_visual.ipynb b/tests/region_label_visual.ipynb index f5fad11..8c79793 100644 --- a/tests/region_label_visual.ipynb +++ b/tests/region_label_visual.ipynb @@ -20,24 +20,25 @@ "cell_type": "code", "collapsed": false, "input": [ - "from pylab import *\n", + "import matplotlib.pyplot as plt\n", "from matplotlib_venn import _region\n", "from tests.utils import point_in_patch\n", "import warnings\n", "warnings.simplefilter(\"error\") # Have warnings raise exceptions in this test\n", "\n", - "def show_region(r, c='r', xlim=(-0.5, 1.5), ylim=(-0.5, 1.5)):\n", - " gca().set_aspect('equal')\n", - " gca().set_xlim(*xlim)\n", - " gca().set_ylim(*ylim)\n", + "\n", + "def show_region(ax, r, c='r', xlim=(-0.5, 1.5), ylim=(-0.5, 1.5)):\n", + " ax.set_aspect('equal')\n", + " ax.set_xlim(*xlim)\n", + " ax.set_ylim(*ylim)\n", " p = r.make_patch()\n", " if p is not None:\n", " p.set_color(c)\n", " p.set_ec('none')\n", " p.set_alpha(0.5)\n", - " gca().add_patch(p)\n", + " ax.add_patch(p)\n", " lblpos = r.label_position()\n", - " scatter(lblpos[0], lblpos[1])\n", + " ax.scatter(lblpos[0], lblpos[1])\n", " assert point_in_patch(p, lblpos)" ], "language": "python", @@ -51,7 +52,9 @@ "input": [ "# For circles, the label is positioned in the center\n", "vcr = _region.VennCircleRegion((0.5, 0.5), 0.5)\n", - "show_region(vcr)" + "\n", + "fig, ax = plt.subplots()\n", + "show_region(ax, vcr)" ], "language": "python", "metadata": {}, @@ -73,7 +76,10 @@ "input": [ "# For two-arc regions, the label is positioned in the middle between the two arcs\n", "twoarc1, twoarc2 = vcr.subtract_and_intersect_circle((1.0, 0.5), 0.5)\n", - "subplot(121); show_region(twoarc1); subplot(122); show_region(twoarc2)" + "\n", + "fig, axs = plt.subplots(1, 2)\n", + "show_region(axs[0], twoarc1)\n", + "show_region(axs[1], twoarc2)" ], "language": "python", "metadata": {}, @@ -95,7 +101,10 @@ "input": [ "# For three-arc regions, the label is in the middle of the three arcs\n", "threearc1, threearc2 = twoarc1.subtract_and_intersect_circle((1, 0), 0.5)\n", - "subplot(121); show_region(threearc1); subplot(122); show_region(threearc2)" + "\n", + "fig, axs = plt.subplots(1, 2)\n", + "show_region(axs[0], threearc1)\n", + "show_region(axs[1], threearc2)" ], "language": "python", "metadata": {}, @@ -118,7 +127,10 @@ "# For multi-piece regions, the label will be positioned in the largest piece\n", "# For four-arcs, the mean of four edges is simply used\n", "multipiece, fourarc = twoarc1.subtract_and_intersect_circle((0.25, 0.25), 0.35)\n", - "subplot(121); show_region(multipiece); subplot(122); show_region(fourarc)" + "\n", + "fig, axs = plt.subplots(1, 2)\n", + "show_region(axs[0], multipiece)\n", + "show_region(axs[1], fourarc)" ], "language": "python", "metadata": {}, @@ -140,7 +152,8 @@ "input": [ "# An example of bad label positioning\n", "bad_piece, _ = twoarc1.subtract_and_intersect_circle((0.25, 0.25), 0.25)\n", - "show_region(bad_piece); " + "fig, ax = plt.subplots()\n", + "show_region(ax, bad_piece); " ], "language": "python", "metadata": {}, @@ -160,4 +173,4 @@ "metadata": {} } ] -} \ No newline at end of file +} diff --git a/tests/region_visual.ipynb b/tests/region_visual.ipynb index 96539fc..a40c094 100644 --- a/tests/region_visual.ipynb +++ b/tests/region_visual.ipynb @@ -20,38 +20,49 @@ "cell_type": "code", "collapsed": false, "input": [ - "from pylab import *\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", "from matplotlib_venn import _region, _math\n", "import warnings\n", "warnings.simplefilter(\"error\") # Have warnings raise exceptions in this test\n", "\n", - "def show_region(r, c='r', xlim=(-2,2), ylim=(-2,2)):\n", - " gca().set_aspect('equal')\n", - " gca().set_xlim(*xlim)\n", - " gca().set_ylim(*ylim)\n", + "\n", + "def show_region(ax, r, c='r', xlim=(-2,2), ylim=(-2,2)):\n", + " ax.set_aspect('equal')\n", + " ax.set_xlim(*xlim)\n", + " ax.set_ylim(*ylim)\n", " p = r.make_patch()\n", " if p is not None:\n", " p.set_color(c)\n", " p.set_ec('none')\n", " p.set_alpha(0.5)\n", - " gca().add_patch(p)\n", - " \n", - "def test_region_subtraction_intersection(region, center, radius, xlim=(-2, 2), ylim=(-2, 2)):\n", + " ax.add_patch(p)\n", + "\n", + "\n", + "def test_region_subtraction_intersection(region, center, radius, xlim=(-2, 2), ylim=(-2, 2), fig=None):\n", + " if fig is None:\n", + " fig = plt.figure()\n", + " axs = fig.subplots(1, 2)\n", + "\n", " vcr = _region.VennCircleRegion(center, radius)\n", - " subplot(121)\n", - " show_region(region, 'r')\n", - " show_region(vcr, 'b', xlim, ylim)\n", - " subplot(122)\n", + " show_region(axs[0], region, 'r')\n", + " show_region(axs[0], vcr, 'b', xlim, ylim)\n", + "\n", " s, i = region.subtract_and_intersect_circle(center, radius)\n", " s.verify()\n", " i.verify()\n", " assert abs(s.size() + i.size() - region.size()) < _math.tol\n", - " show_region(s, 'r')\n", - " show_region(i, 'm', xlim, ylim)\n", + " show_region(axs[1], s, 'r')\n", + " show_region(axs[1], i, 'm', xlim, ylim)\n", + "\n", + "\n", + "def test_two_circles(c1, r1, c2, r2, xlim, ylim=(-2, 2), suptitle=None):\n", + " fig = plt.figure()\n", + " test_region_subtraction_intersection(_region.VennCircleRegion(c1, r1), c2, r2, xlim,\n", + " fig=fig)\n", + " if suptitle is not None:\n", + " fig.suptitle(suptitle)\n", "\n", - "def test_two_circles(c1, r1, c2, r2, xlim, ylim=(-2, 2)):\n", - " test_region_subtraction_intersection(_region.VennCircleRegion(c1, r1), c2, r2, xlim)\n", - " \n", "r1, r2 = _region.VennCircleRegion((0, 0), 1).subtract_and_intersect_circle((1, 0), 1)\n", "r3, r4 = _region.VennCircleRegion((0, 0), 1).subtract_and_intersect_circle((0.6,0), 0.45)" ], @@ -72,8 +83,8 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_two_circles((0, 0), 1, (1, 0), 1, (-1.5, 2.5))\n", - "suptitle(\"The usual case\");" + "test_two_circles((0, 0), 1, (1, 0), 1, (-1.5, 2.5),\n", + " suptitle=\"The usual case\")" ], "language": "python", "metadata": {}, @@ -93,8 +104,8 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_two_circles((0, 0), 1, (0.5, 0), 0.5, (-1.5, 1.5))\n", - "suptitle(\"One smaller inside the other\");" + "test_two_circles((0, 0), 1, (0.5, 0), 0.5, (-1.5, 1.5),\n", + " suptitle=\"One smaller inside the other\")" ], "language": "python", "metadata": {}, @@ -114,8 +125,8 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_two_circles((0, 0), 1, (0, 0), 1, (-1.5, 1.5))\n", - "suptitle(\"Two equal circles\");" + "test_two_circles((0, 0), 1, (0, 0), 1, (-1.5, 1.5),\n", + " suptitle=\"Two equal circles\")" ], "language": "python", "metadata": {}, @@ -135,8 +146,8 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_two_circles((0.6, 0), 0.5, (0, 0), 1, (-1.5, 1.5))\n", - "suptitle(\"Subtracting larger from smaller\");" + "test_two_circles((0.6, 0), 0.5, (0, 0), 1, (-1.5, 1.5),\n", + " suptitle=\"Subtracting larger from smaller\")" ], "language": "python", "metadata": {}, @@ -156,8 +167,8 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_two_circles((0.5, 0), 0.5, (0, 0), 1, (-1.5, 1.5))\n", - "suptitle(\"Subtracting larger from smaller, corner case\");" + "test_two_circles((0.5, 0), 0.5, (0, 0), 1, (-1.5, 1.5),\n", + " suptitle=\"Subtracting larger from smaller, corner case\")" ], "language": "python", "metadata": {}, @@ -177,8 +188,8 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_two_circles((0, 0), 1, (1.5, 0), 0.5, (-1.5, 2.5))\n", - "suptitle(\"Subtracting external circle\");" + "test_two_circles((0, 0), 1, (1.5, 0), 0.5, (-1.5, 2.5),\n", + " suptitle=\"Subtracting external circle\")" ], "language": "python", "metadata": {}, @@ -198,8 +209,8 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_two_circles((0, 0), 1, (1.4, 0), 0.5, (-1.5, 2.5))\n", - "suptitle(\"Small intersection\");" + "test_two_circles((0, 0), 1, (1.4, 0), 0.5, (-1.5, 2.5),\n", + " suptitle=\"Small intersection\")" ], "language": "python", "metadata": {}, @@ -440,7 +451,7 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_region_subtraction_intersection(r2, (0.5, 0), sin(pi/3))" + "test_region_subtraction_intersection(r2, (0.5, 0), np.sin(np.pi/3))" ], "language": "python", "metadata": {}, @@ -948,7 +959,7 @@ "cell_type": "code", "collapsed": false, "input": [ - "test_region_subtraction_intersection(r1, (0.5, np.sin(pi/3)), 0.5)" + "test_region_subtraction_intersection(r1, (0.5, np.sin(np.pi/3)), 0.5)" ], "language": "python", "metadata": {}, @@ -1022,7 +1033,7 @@ "cell_type": "code", "collapsed": false, "input": [ - "r = np.linalg.norm(np.array([-1, 0]) - np.array([0.5, sin(np.pi/3)]))\n", + "r = np.linalg.norm(np.array([-1, 0]) - np.array([0.5, np.sin(np.pi/3)]))\n", "test_region_subtraction_intersection(r2, (-1, 0), r)" ], "language": "python", @@ -1081,11 +1092,12 @@ "cell_type": "code", "collapsed": false, "input": [ + "fig, ax = plt.subplots()\n", "for r in rs:\n", - " show_region(r)\n", + " show_region(ax, r)\n", " lpos = r.label_position()\n", " if lpos is not None:\n", - " scatter(lpos[0], lpos[1])" + " ax.scatter(lpos[0], lpos[1])" ], "language": "python", "metadata": {}, @@ -1105,4 +1117,4 @@ "metadata": {} } ] -} \ No newline at end of file +} diff --git a/tests/utils.py b/tests/utils.py index 6355c9c..c0b9729 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -63,13 +63,5 @@ def exec_ipynb(filename): code = ''.join(cell['input']) if sys.version_info.major == 2: exec("exec code in locals()") - elif sys.version_info.minor >= 5: - # Ignore spurious MatplotlibDeprecationWarning - # See: https://github.com/matplotlib/matplotlib/issues/12513 - from matplotlib.cbook.deprecation import MatplotlibDeprecationWarning - import warnings - with warnings.catch_warnings(): - warnings.filterwarnings('ignore', category=MatplotlibDeprecationWarning) - exec(code, locals()) else: - exec(code, locals()) \ No newline at end of file + exec(code, locals()) From 47fae0cd9af649fca092b35606fd0a82e362ce8b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 20 Aug 2022 20:43:00 -0400 Subject: [PATCH 2/2] Close figures in each test notebook cell These are normally closed by the matplotlib-inline backend, if you are running the notebook itself, so there's no need for explicit closing. However, the tests `exec` each cell in a non-notebook process, so this automatic closing does not occur and needs to be done explicitly. Doing so prevents a "too many figures have been opened" warning from Matplotlib. --- tests/utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/utils.py b/tests/utils.py index c0b9729..baf0b8e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -9,6 +9,8 @@ ''' import json import sys + +import matplotlib.pyplot as plt from matplotlib.patches import Circle from matplotlib.pyplot import scatter @@ -65,3 +67,9 @@ def exec_ipynb(filename): exec("exec code in locals()") else: exec(code, locals()) + + # Explicitly close any figures created by this cell, which + # would normally (in a notebook) be done by the + # matplotlib-inline backend. This prevents a warning about "too + # many figures opened" from Matplotlib. + plt.close('all')