diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f6e9bbf..c331d72 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12", "3.13"] runs-on: ubuntu-latest steps: @@ -45,7 +45,12 @@ jobs: pip install -U pip pip install .[dev] - name: Run tests - run: pytest --mpl --verbose + run: pytest --mpl --verbose --mpl-generate-summary=html --mpl-results-path=./results + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: pytest-mpl-results-${{ matrix.python-version }} + path: ./results - name: Run coverage if: contains(env.USING_COVERAGE, matrix.python-version) run: | diff --git a/mpl_template/__init__.py b/mpl_template/__init__.py index 5f1e9e7..6c31635 100644 --- a/mpl_template/__init__.py +++ b/mpl_template/__init__.py @@ -1,5 +1,5 @@ from .template import Template, insert_image -__version__ = "0.5.0" +__version__ = "0.5.1a" __all__ = ["insert_image", "Template"] diff --git a/mpl_template/template.py b/mpl_template/template.py index 0d3fef4..5f8a2f1 100644 --- a/mpl_template/template.py +++ b/mpl_template/template.py @@ -175,7 +175,7 @@ def insert_image( relative to the given matplotlib.Axes object. scale = 0.5 will scale the image to half of the given matplotlib.Axes object. - dpi : int, optonal (default=300) + dpi : int, optional (default=300) The Dots (pixel) Per Inch of the image. expand : bool, optional (default=False) If true, the image will expand to fill the axes @@ -231,12 +231,7 @@ def insert_image( if TAGS is None or Image is None: # pragma: no cover raise ImportError("The `pillow` library is required to manipulate images.") - if "xticks" not in kwargs: - kwargs["xticks"] = [] - if "yticks" not in kwargs: - kwargs["yticks"] = [] - if "zorder" not in kwargs: - kwargs["zorder"] = 1 + kwargs = {"xticks": [], "yticks": [], "zorder": 1} | kwargs imgaxes = ax.figure.add_axes(ax.get_position(), **kwargs) bbox = ax.get_window_extent().transformed( @@ -579,7 +574,7 @@ def add_watermark(self, text=None): text, fontsize=24, color="r", - fontname="Arial", + fontname="sans-serif", fontweight="bold", zorder=1000, horizontalalignment="left", @@ -685,16 +680,18 @@ def setup_figure(self) -> figure.Figure: return self.fig - def blank(self) -> figure.Figure: + def blank(self, with_labels=True) -> figure.Figure: self.add_frame() - for ax in self.add_titleblock(): - ax.text( - 0.5, - 0.5, - '"{}"'.format(ax.get_label()), - va="center", - ha="center", - size=12, - ) + axes = self.add_titleblock() + if with_labels: + for ax in axes: + ax.text( + 0.5, + 0.5, + '"{}"'.format(ax.get_label()), + va="center", + ha="center", + size=12, + ) self.watermark.remove() return self.fig diff --git a/mpl_template/tests/baseline_images/test_blank.png b/mpl_template/tests/baseline_images/test_blank.png index d64b934..a17bf00 100644 Binary files a/mpl_template/tests/baseline_images/test_blank.png and b/mpl_template/tests/baseline_images/test_blank.png differ diff --git a/mpl_template/tests/baseline_images/test_custom_spans.png b/mpl_template/tests/baseline_images/test_custom_spans.png index 0bcbc6c..4af8c4c 100644 Binary files a/mpl_template/tests/baseline_images/test_custom_spans.png and b/mpl_template/tests/baseline_images/test_custom_spans.png differ diff --git a/mpl_template/tests/baseline_images/test_custom_titleblock.png b/mpl_template/tests/baseline_images/test_custom_titleblock.png index 644553c..e854404 100644 Binary files a/mpl_template/tests/baseline_images/test_custom_titleblock.png and b/mpl_template/tests/baseline_images/test_custom_titleblock.png differ diff --git a/mpl_template/tests/baseline_images/test_fancy_titleblock.png b/mpl_template/tests/baseline_images/test_fancy_titleblock.png index 3794e32..3922dda 100644 Binary files a/mpl_template/tests/baseline_images/test_fancy_titleblock.png and b/mpl_template/tests/baseline_images/test_fancy_titleblock.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_file.png b/mpl_template/tests/baseline_images/test_insert_image_from_file.png index 9c882f4..0d77e33 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_file.png and b/mpl_template/tests/baseline_images/test_insert_image_from_file.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_file_shrink_half.png b/mpl_template/tests/baseline_images/test_insert_image_from_file_shrink_half.png index 05835a6..6a5dc41 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_file_shrink_half.png and b/mpl_template/tests/baseline_images/test_insert_image_from_file_shrink_half.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x.png b/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x.png index 6b0208f..957d112 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x.png and b/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x_expand.png b/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x_expand.png index ecc331d..fb5a892 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x_expand.png and b/mpl_template/tests/baseline_images/test_insert_image_from_file_zoom_10x_expand.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_url.png b/mpl_template/tests/baseline_images/test_insert_image_from_url.png index 9c882f4..0d77e33 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_url.png and b/mpl_template/tests/baseline_images/test_insert_image_from_url.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_url_shrink_half.png b/mpl_template/tests/baseline_images/test_insert_image_from_url_shrink_half.png index 05835a6..6a5dc41 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_url_shrink_half.png and b/mpl_template/tests/baseline_images/test_insert_image_from_url_shrink_half.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x.png b/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x.png index 6b0208f..957d112 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x.png and b/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x.png differ diff --git a/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x_expand.png b/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x_expand.png index ecc331d..fb5a892 100644 Binary files a/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x_expand.png and b/mpl_template/tests/baseline_images/test_insert_image_from_url_zoom_10x_expand.png differ diff --git a/mpl_template/tests/baseline_images/test_titleblock_on_left.png b/mpl_template/tests/baseline_images/test_titleblock_on_left.png index 9699c09..c8f2a68 100644 Binary files a/mpl_template/tests/baseline_images/test_titleblock_on_left.png and b/mpl_template/tests/baseline_images/test_titleblock_on_left.png differ diff --git a/mpl_template/tests/baseline_images/test_zero_margins.png b/mpl_template/tests/baseline_images/test_zero_margins.png index d313be0..f26b7ed 100644 Binary files a/mpl_template/tests/baseline_images/test_zero_margins.png and b/mpl_template/tests/baseline_images/test_zero_margins.png differ diff --git a/mpl_template/tests/test_template.py b/mpl_template/tests/test_template.py index 3a3c1c0..b9fdd34 100644 --- a/mpl_template/tests/test_template.py +++ b/mpl_template/tests/test_template.py @@ -12,7 +12,6 @@ DEMO_PNG_URL = "https://raw.githubusercontent.com/austinorr/mpl-template/14496e1965e8b360093e0a559ae3f9aba6205a56/template/tests/img/polar_bar_demo.png" DEMO_PNG_FILE = str(files("mpl_template.tests.img") / "polar_bar_demo.png") -IMG_TOL = 10 BASELINE_DIR = "baseline_images" SCRIPTNAME = str(Path("mpl_template") / "tests" / "test_template.py") @@ -31,7 +30,7 @@ def test_calc_extents(size, scale, expected): @pytest.mark.parametrize("i", range(4)) @pytest.mark.mpl_image_compare( baseline_dir=BASELINE_DIR, - tolerance=IMG_TOL, + tolerance=3, filename="grace_hopper.png", savefig_kwargs={"dpi": 96}, ) @@ -47,16 +46,19 @@ def test__apply_exif_rotation(i): return fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare( + baseline_dir=BASELINE_DIR, + tolerance=4, # higher tolerance since this one includes freetype text +) def test_blank(): - testfig = template.Template(figsize=(8.5, 11), scriptname="") + testfig = template.Template(figsize=(5, 3), scriptname="") testfig.path_text = SCRIPTNAME _ = testfig.blank() return testfig.fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_url(): url = DEMO_PNG_URL fig, ax = plt.subplots(figsize=(9, 9)) @@ -71,7 +73,7 @@ def test_insert_svg_image_from_url(): _ = template.insert_image(ax, url, scale=1) -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_url_shrink_half(): url = DEMO_PNG_URL fig, ax = plt.subplots(figsize=(9, 9)) @@ -79,7 +81,7 @@ def test_insert_image_from_url_shrink_half(): return fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_url_zoom_10x(): url = DEMO_PNG_URL fig, ax = plt.subplots(figsize=(9, 9)) @@ -87,7 +89,7 @@ def test_insert_image_from_url_zoom_10x(): return fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_url_zoom_10x_expand(): url = DEMO_PNG_URL fig, ax = plt.subplots(figsize=(9, 9)) @@ -95,7 +97,7 @@ def test_insert_image_from_url_zoom_10x_expand(): return fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_file(): file = DEMO_PNG_FILE @@ -104,7 +106,7 @@ def test_insert_image_from_file(): return fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_file_shrink_half(): file = DEMO_PNG_FILE @@ -113,7 +115,7 @@ def test_insert_image_from_file_shrink_half(): return fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_file_zoom_10x(): file = DEMO_PNG_FILE @@ -122,7 +124,7 @@ def test_insert_image_from_file_zoom_10x(): return fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, remove_text=True) def test_insert_image_from_file_zoom_10x_expand(): file = DEMO_PNG_FILE @@ -132,7 +134,7 @@ def test_insert_image_from_file_zoom_10x_expand(): @pytest.mark.mpl_image_compare( - baseline_dir=BASELINE_DIR, tolerance=IMG_TOL, filename="test_custom_spans.png" + baseline_dir=BASELINE_DIR, filename="test_custom_spans.png" ) @pytest.mark.parametrize("base", [None, 10]) def test_custom_spans(base): @@ -149,13 +151,13 @@ def test_custom_spans(base): figsize=(5, 3), scriptname="", titleblock_content=test, base=base ) testfig.path_text = SCRIPTNAME - _ = testfig.blank() + _ = testfig.blank(with_labels=False) return testfig.fig @pytest.mark.mpl_image_compare( - baseline_dir=BASELINE_DIR, tolerance=IMG_TOL, filename="test_custom_spans.png" + baseline_dir=BASELINE_DIR, filename="test_custom_spans.png" ) def test_custom_spans_100(): test = [ @@ -171,14 +173,13 @@ def test_custom_spans_100(): figsize=(5, 3), scriptname="", titleblock_content=test, base=100 ) testfig.path_text = SCRIPTNAME - _ = testfig.blank() + _ = testfig.blank(with_labels=False) return testfig.fig @pytest.mark.mpl_image_compare( baseline_dir=BASELINE_DIR, - tolerance=IMG_TOL, filename="test_titleblock_on_left.png", ) @pytest.mark.parametrize("base", [None, 10, 100]) @@ -186,21 +187,21 @@ def test_titleblock_on_left(base): testfig = template.Template(figsize=(8.5, 11), scriptname="", base=base) testfig.gstitleblock = testfig.gsfig[ -(testfig.bottom + testfig.t_h) or None : -testfig.bottom or None, - (testfig.left) or None : -(testfig.left + testfig.t_w) or None, + (testfig.left) or None : (testfig.left + testfig.t_w) or None, ] - _ = testfig.blank() + _ = testfig.blank(with_labels=False) return testfig.fig -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR) def test_zero_margins(): testfig = template.Template( - figsize=(8.5, 11), scriptname="tests.py", margins=(0, 0, 0, 0) + figsize=(5, 3), scriptname="tests.py", margins=(0, 0, 0, 0) ) - _ = testfig.blank() + _ = testfig.blank(with_labels=False) return testfig.fig @@ -219,7 +220,10 @@ def test_bad_margins(bad_margin): ) -@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=IMG_TOL) +@pytest.mark.mpl_image_compare( + baseline_dir=BASELINE_DIR, + tolerance=8, # increase tolerance for fonts +) def test_custom_titleblock(): custom = [ { @@ -267,7 +271,7 @@ def test_custom_titleblock(): ] testfig = template.Template( - figsize=(8.5, 11), scriptname="", titleblock_content=custom + figsize=(5, 3), scriptname="", titleblock_content=custom ) testfig.path_text = SCRIPTNAME @@ -279,7 +283,7 @@ def test_custom_titleblock(): @pytest.mark.parametrize("base", [None, 10, 100]) @pytest.mark.mpl_image_compare( baseline_dir=BASELINE_DIR, - tolerance=IMG_TOL, + tolerance=8, # increase tolerance for fonts filename="test_fancy_titleblock.png", ) def test_fancy_titleblock(base): @@ -329,7 +333,7 @@ def test_fancy_titleblock(base): ] testfig = template.Template( - figsize=(8.5, 11), scriptname="", titleblock_content=fancy, base=base + figsize=(5, 3), scriptname="", titleblock_content=fancy, base=base ) testfig.path_text = SCRIPTNAME _ = testfig.setup_figure() diff --git a/pyproject.toml b/pyproject.toml index 78bfce8..d159e2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "mpl_template" description = "mpl-template: matplotlib report template constructor" readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10" license = { text = "BSD-3-Clause" } authors = [{ name = "Austin Orr", email = "austinmartinorr@gmail.com" }] classifiers = [ @@ -15,7 +15,6 @@ classifiers = [ "Programming Language :: Python", "Intended Audience :: Science/Research", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -27,6 +26,7 @@ dynamic = ["version"] all = ["requests", "pillow"] dev = [ "mpl-template[all]", + "matplotlib>=3.10,<3.11", # pins mpl & freetype version "coverage>=6.0.0", "pytest>=7.0.0", "pytest-cov>=4.1",