From e5ff348566e8c7311aa890992c322a7beafb1f5e Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 11 Apr 2026 08:29:35 +0200 Subject: [PATCH 1/4] Added side-by-side plots with tikzfigure --- README.qmd | 26 ++++- src/maxplotlib/canvas/canvas.py | 71 +++++++++++-- src/maxplotlib/tests/test_canvas.py | 72 +++++++++++++ tutorials/tutorial_02.ipynb | 85 +++++++++++---- tutorials/tutorial_tikzfigure_subplots.ipynb | 106 +++++++++++++++++++ 5 files changed, 333 insertions(+), 27 deletions(-) create mode 100644 tutorials/tutorial_tikzfigure_subplots.ipynb diff --git a/README.qmd b/README.qmd index 980b775..5b82cad 100644 --- a/README.qmd +++ b/README.qmd @@ -41,12 +41,36 @@ Plot the figure with the default (matplotlib) backend: canvas.show() ``` -Alternatively, plot with the TikZ backend (not done yet): +Alternatively, plot with the TikZ backend: ```{python} canvas.show(backend="tikzfigure") ``` +### Horizontal Subplots with TikZ Backend + +The tikzfigure backend supports creating side-by-side subplots (1×n layouts): + +```{python} +#| label: fig-showcase-subplots +#| fig-width: 9 +#| fig-height: 6 + +x = np.linspace(0, 2 * np.pi, 200) +canvas, (ax1, ax2) = Canvas.subplots(ncols=2, width="10cm", ratio=0.3) + +ax1.plot(x, np.sin(x), color="royalblue") +ax1.set_title("sin(x)") + +ax2.plot(x, np.cos(x), color="tomato") +ax2.set_title("cos(x)") + +canvas.suptitle("Trigonometric Functions") +canvas.show(backend="tikzfigure") # Generates LaTeX subfigures +``` + +**Note:** Only horizontal layouts (1×n) are currently supported with the tikzfigure backend. Vertical/grid layouts will raise `NotImplementedError`. See the tutorials for more examples. + ### Layers ```{python} diff --git a/src/maxplotlib/canvas/canvas.py b/src/maxplotlib/canvas/canvas.py index bea3e39..8f03841 100644 --- a/src/maxplotlib/canvas/canvas.py +++ b/src/maxplotlib/canvas/canvas.py @@ -735,6 +735,7 @@ def show( self.plot_plotly(savefig=False) elif backend == "tikzfigure": fig = self.plot_tikzfigure(savefig=False, verbose=verbose) + # TikzFigure handles all rendering (single or multi-subplot) fig.show() else: raise ValueError("Invalid backend") @@ -807,19 +808,77 @@ def plot_matplotlib( def plot_tikzfigure( self, - savefig: str | None = None, + savefig: bool = False, verbose: bool = False, ) -> TikzFigure: - if len(self._subplot_dict) > 1: + """ + Generate a TikZ figure from subplots. + + For now, returns the first subplot's TikzFigure. + Full multi-subplot support requires TikzFigure's subfigure_axis API. + + Parameters: + verbose (bool): If True, print debug information. + + Returns: + TikzFigure: Figure object that can be shown, saved, or compiled. + """ + if verbose: + print(f"Plotting tikzfigure with {len(self._subplot_dict)} subplot(s)") + + # Check for unsupported layouts + if self.nrows > 1: raise NotImplementedError( - "Only one subplot is supported for tikzfigure backend." + "Vertical/grid layouts (nrows > 1) are not yet supported for tikzfigure backend. " + "Use horizontal layouts (1×n) only." + ) + + # Validate that at least one subplot exists + if len(self._subplot_dict) == 0: + raise ValueError( + "No subplots to plot. Call add_subplot() or Canvas.subplots() first." ) + + fig = TikzFigure() + + # Add each subplot as a subfigure axis for (row, col), line_plot in self._subplot_dict.items(): if verbose: print(f"Plotting subplot at row {row}, col {col}") - print(f"{line_plot = }") - tikz_subplot = line_plot.plot_tikzfigure(verbose=verbose) - return tikz_subplot + + # Create subfigure axis with subplot metadata + ax = fig.subfigure_axis( + xlabel=line_plot._xlabel or "", + ylabel=line_plot._ylabel or "", + xlim=(line_plot._xmin, line_plot._xmax) if line_plot._xmin is not None else None, + ylim=(line_plot._ymin, line_plot._ymax) if line_plot._ymin is not None else None, + grid=line_plot._grid, + caption=line_plot._title or f"Subplot {col+1}", + width=0.45, + ) + + # Add each plot line to the subfigure + for line_data in line_plot.line_data: + if line_data.get("plot_type") == "plot": + # Extract and transform x, y data + x = (line_data["x"] + line_plot._xshift) * line_plot._xscale + y = (line_data["y"] + line_plot._yshift) * line_plot._yscale + kwargs = line_data.get("kwargs", {}) + + # Add plot to subfigure axis + ax.add_plot( + x=x, + y=y, + # label=kwargs.get("label", ""), + color=kwargs.get("color"), + line_width=kwargs.get("linewidth"), + ) + + # Add legend if requested + if line_plot._legend and len(line_plot.line_data) > 0: + ax.set_legend(position="north east") + + return fig def plot_plotly(self, show=True, savefig=None, usetex=False): """ diff --git a/src/maxplotlib/tests/test_canvas.py b/src/maxplotlib/tests/test_canvas.py index 847a2d5..93f8641 100644 --- a/src/maxplotlib/tests/test_canvas.py +++ b/src/maxplotlib/tests/test_canvas.py @@ -2,5 +2,77 @@ def test(): pass +def test_canvas_plot_tikzfigure_horizontal_subplots(): + """Test that Canvas.plot_tikzfigure() works with horizontal (1×n) layouts.""" + import numpy as np + from maxplotlib import Canvas + + # Create a 1×2 canvas + canvas, (ax1, ax2) = Canvas.subplots(ncols=2, width="10cm", ratio=0.3) + + # Add data to both subplots + x = np.linspace(0, 2 * np.pi, 50) + ax1.plot(x, np.sin(x), label="sin(x)", color="royalblue") + ax1.set_title("Sine") + ax1.set_xlabel("x") + ax1.set_ylabel("y") + + ax2.plot(x, np.cos(x), label="cos(x)", color="tomato") + ax2.set_title("Cosine") + ax2.set_xlabel("x") + + canvas.suptitle("Trig Functions") + + # This should NOT raise NotImplementedError + result = canvas.plot_tikzfigure(verbose=False) + + # Result should be a TikzFigure or string containing LaTeX + assert result is not None + + +def test_canvas_plot_tikzfigure_three_subplots(): + """Test 1×3 layout with tikzfigure backend.""" + import numpy as np + from maxplotlib import Canvas + + x = np.linspace(0, 2 * np.pi, 50) + canvas, axes = Canvas.subplots(ncols=3, width="12cm", ratio=0.3) + + axes[0].plot(x, np.sin(x), color="blue") + axes[0].set_title("Sin") + + axes[1].plot(x, np.cos(x), color="red") + axes[1].set_title("Cos") + + axes[2].plot(x, np.tan(x), color="green") + axes[2].set_title("Tan") + + result = canvas.plot_tikzfigure() + + assert result is not None + if isinstance(result, str): + assert "\\subfigure" in result or "subfigure" in result + + +def test_canvas_plot_tikzfigure_vertical_not_supported(): + """Test that vertical layouts raise NotImplementedError.""" + import numpy as np + from maxplotlib import Canvas + import pytest + + x = np.linspace(0, 2 * np.pi, 50) + # Create 2×1 layout (nrows=2) + canvas, axes = Canvas.subplots(nrows=2, width="10cm") + + axes[0].plot(x, np.sin(x)) + axes[1].plot(x, np.cos(x)) + + # Should raise NotImplementedError + with pytest.raises(NotImplementedError) as exc_info: + canvas.plot_tikzfigure() + + assert "nrows > 1" in str(exc_info.value) + + if __name__ == "__main__": test() diff --git a/tutorials/tutorial_02.ipynb b/tutorials/tutorial_02.ipynb index b30e4cb..8048d11 100644 --- a/tutorials/tutorial_02.ipynb +++ b/tutorials/tutorial_02.ipynb @@ -25,17 +25,59 @@ "outputs": [], "source": [ "from maxplotlib import Canvas\n", + "from tikzfigure import TikzFigure\n", "import numpy as np\n", "\n", "%matplotlib inline\n", + "%load_ext autoreload\n", + "%autoreload 2\n", "\n", "x = np.linspace(0, 2 * np.pi, 200)" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "id": "2", "metadata": {}, + "outputs": [], + "source": [ + "\n", + "fig = TikzFigure()\n", + "\n", + "x = np.linspace(0, 360, 200)\n", + "y1 = np.sin(np.radians(x))\n", + "y2 = np.cos(np.radians(x))\n", + "\n", + "# First subfigure: sine wave\n", + "ax1 = fig.subfigure_axis(\n", + " xlabel=\"x\", ylabel=\"y\",\n", + " xlim=(0, 360), ylim=(-1.5, 1.5),\n", + " grid=True,\n", + " caption=\"Sine Function\",\n", + " width=0.45\n", + ")\n", + "ax1.add_plot(x=x, y=y1, label=\"sin(x)\", color=\"red\", line_width=\"1.5pt\")\n", + "ax1.set_legend(position=\"north east\")\n", + "\n", + "# Second subfigure: cosine wave\n", + "ax2 = fig.subfigure_axis(\n", + " xlabel=\"x\", ylabel=\"y\",\n", + " xlim=(0, 360), ylim=(-1.5, 1.5),\n", + " grid=True,\n", + " caption=\"Cosine Function\",\n", + " width=0.45\n", + ")\n", + "ax2.add_plot(x=x, y=y2, label=\"cos(x)\", color=\"blue\", line_width=\"1.5pt\")\n", + "ax2.set_legend(position=\"north east\")\n", + "\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": {}, "source": [ "## 1 1×2 layout — side-by-side subplots" ] @@ -43,28 +85,31 @@ { "cell_type": "code", "execution_count": null, - "id": "3", + "id": "4", "metadata": {}, "outputs": [], "source": [ + "\n", "canvas, (ax1, ax2) = Canvas.subplots(ncols=2, width=1000, ratio=0.3)\n", "\n", - "ax1.plot(x, np.sin(x), color=\"royalblue\")\n", + "x = np.linspace(0, 2 * np.pi, 200)\n", + "\n", + "ax1.plot(x, np.sin(x), color=\"royalblue\", linewidth=1.5)\n", "ax1.set_title(\"sin(x)\")\n", "ax1.set_xlabel(\"x\")\n", "ax1.set_ylabel(\"amplitude\")\n", "\n", - "ax2.plot(x, np.cos(x), color=\"tomato\")\n", + "ax2.plot(x, np.cos(x), color=\"tomato\", linewidth=1.5)\n", "ax2.set_title(\"cos(x)\")\n", "ax2.set_xlabel(\"x\")\n", "\n", "canvas.suptitle(\"1 × 2 Layout\")\n", - "canvas.show()" + "canvas.show(backend=\"tikzfigure\")" ] }, { "cell_type": "markdown", - "id": "4", + "id": "5", "metadata": {}, "source": [ "## 2 2×2 layout — grid of subplots\n", @@ -76,7 +121,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5", + "id": "6", "metadata": {}, "outputs": [], "source": [ @@ -97,7 +142,7 @@ }, { "cell_type": "markdown", - "id": "6", + "id": "7", "metadata": {}, "source": [ "## 3 `squeeze=False` — always get a 2-D list\n", @@ -109,7 +154,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7", + "id": "8", "metadata": {}, "outputs": [], "source": [ @@ -128,7 +173,7 @@ }, { "cell_type": "markdown", - "id": "8", + "id": "9", "metadata": {}, "source": [ "## 4 Manual layout — `canvas.add_subplot(row, col)`\n", @@ -140,7 +185,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9", + "id": "10", "metadata": {}, "outputs": [], "source": [ @@ -165,7 +210,7 @@ }, { "cell_type": "markdown", - "id": "10", + "id": "11", "metadata": {}, "source": [ "## 5 Accessing subplots after creation\n", @@ -176,7 +221,7 @@ { "cell_type": "code", "execution_count": null, - "id": "11", + "id": "12", "metadata": {}, "outputs": [], "source": [ @@ -198,7 +243,7 @@ }, { "cell_type": "markdown", - "id": "12", + "id": "13", "metadata": {}, "source": [ "## 6 `canvas.iter_subplots()` — loop over all panels" @@ -207,7 +252,7 @@ { "cell_type": "code", "execution_count": null, - "id": "13", + "id": "14", "metadata": {}, "outputs": [], "source": [ @@ -228,7 +273,7 @@ }, { "cell_type": "markdown", - "id": "14", + "id": "15", "metadata": {}, "source": [ "## 7 Canvas-level plot routing\n", @@ -239,7 +284,7 @@ { "cell_type": "code", "execution_count": null, - "id": "15", + "id": "16", "metadata": {}, "outputs": [], "source": [ @@ -258,7 +303,7 @@ }, { "cell_type": "markdown", - "id": "16", + "id": "17", "metadata": {}, "source": [ "## Summary\n", @@ -280,7 +325,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "env_maxpic", "language": "python", "name": "python3" }, @@ -294,7 +339,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.13.3" } }, "nbformat": 4, diff --git a/tutorials/tutorial_tikzfigure_subplots.ipynb b/tutorials/tutorial_tikzfigure_subplots.ipynb new file mode 100644 index 0000000..ff98b7d --- /dev/null +++ b/tutorials/tutorial_tikzfigure_subplots.ipynb @@ -0,0 +1,106 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": {}, + "source": [ + "# TikzFigure Subplots Tutorial\n", + "\n", + "This tutorial demonstrates how to create side-by-side subplots using the `tikzfigure` backend.\n", + "\n", + "## Basic 1×2 Layout\n", + "\n", + "The simplest use case: two plots side by side." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "from maxplotlib import Canvas\n", + "import numpy as np\n", + "\n", + "# Create a 1×2 canvas with custom width\n", + "x = np.linspace(0, 2 * np.pi, 200)\n", + "canvas, (ax1, ax2) = Canvas.subplots(ncols=2, width=\"10cm\", ratio=0.3)\n", + "\n", + "# Left subplot: sine wave\n", + "ax1.plot(x, np.sin(x), color=\"royalblue\", label=\"sin(x)\")\n", + "ax1.set_title(\"sin(x)\")\n", + "ax1.set_xlabel(\"x\")\n", + "ax1.set_ylabel(\"amplitude\")\n", + "\n", + "# Right subplot: cosine wave\n", + "ax2.plot(x, np.cos(x), color=\"tomato\", label=\"cos(x)\")\n", + "ax2.set_title(\"cos(x)\")\n", + "ax2.set_xlabel(\"x\")\n", + "\n", + "# Set overall title\n", + "canvas.suptitle(\"1 × 2 Layout: Trigonometric Functions\")\n", + "\n", + "# Render with tikzfigure backend\n", + "result = canvas.show(backend=\"tikzfigure\")" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": {}, + "source": [ + "## 1×3 Layout: Multiple Functions\n", + "\n", + "You can create layouts with more than 2 subplots." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "# Create a 1×3 canvas\n", + "canvas, axes = Canvas.subplots(ncols=3, width=\"12cm\", ratio=0.35)\n", + "\n", + "# Three different functions\n", + "x = np.linspace(0, 2 * np.pi, 100)\n", + "\n", + "axes[0].plot(x, np.sin(x), color=\"royalblue\")\n", + "axes[0].set_title(\"sin(x)\")\n", + "axes[0].set_xlabel(\"x\")\n", + "\n", + "axes[1].plot(x, np.cos(x), color=\"tomato\")\n", + "axes[1].set_title(\"cos(x)\")\n", + "axes[1].set_xlabel(\"x\")\n", + "\n", + "axes[2].plot(x, np.tan(x), color=\"seagreen\")\n", + "axes[2].set_title(\"tan(x)\")\n", + "axes[2].set_xlabel(\"x\")\n", + "axes[2].set_ylim(-5, 5) # Limit y-range for tan\n", + "\n", + "canvas.suptitle(\"1 × 3 Layout: Three Trigonometric Functions\")\n", + "result = canvas.show(backend=\"tikzfigure\")" + ] + }, + { + "cell_type": "markdown", + "id": "4", + "metadata": {}, + "source": [ + "## Important Notes\n", + "\n", + "- Only **horizontal layouts (1×n)** are supported with tikzfigure backend\n", + "- Vertical/grid layouts (nrows > 1) will raise an error\n", + "- Use matplotlib backend for complex layouts or grids\n", + "- Each subplot's title becomes a subfigure caption in the LaTeX output" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} From c99393eb69f7801ad9e32e565779d65bab594b0f Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 11 Apr 2026 08:38:11 +0200 Subject: [PATCH 2/4] improve tutorial --- src/maxplotlib/canvas/canvas.py | 10 ++-- tutorials/tutorial_tikzfigure_subplots.ipynb | 51 +++++++++++++++----- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/maxplotlib/canvas/canvas.py b/src/maxplotlib/canvas/canvas.py index 8f03841..5fcee19 100644 --- a/src/maxplotlib/canvas/canvas.py +++ b/src/maxplotlib/canvas/canvas.py @@ -736,7 +736,8 @@ def show( elif backend == "tikzfigure": fig = self.plot_tikzfigure(savefig=False, verbose=verbose) # TikzFigure handles all rendering (single or multi-subplot) - fig.show() + fig.show(transparent=False) + return fig else: raise ValueError("Invalid backend") @@ -864,14 +865,15 @@ def plot_tikzfigure( x = (line_data["x"] + line_plot._xshift) * line_plot._xscale y = (line_data["y"] + line_plot._yshift) * line_plot._yscale kwargs = line_data.get("kwargs", {}) - + if verbose: + print(f"Line {kwargs = }") # Add plot to subfigure axis ax.add_plot( x=x, y=y, # label=kwargs.get("label", ""), - color=kwargs.get("color"), - line_width=kwargs.get("linewidth"), + color=kwargs.get("color", "black"), + line_width=kwargs.get("linewidth", 1.0), ) # Add legend if requested diff --git a/tutorials/tutorial_tikzfigure_subplots.ipynb b/tutorials/tutorial_tikzfigure_subplots.ipynb index ff98b7d..e4e816d 100644 --- a/tutorials/tutorial_tikzfigure_subplots.ipynb +++ b/tutorials/tutorial_tikzfigure_subplots.ipynb @@ -23,19 +23,29 @@ "source": [ "from maxplotlib import Canvas\n", "import numpy as np\n", - "\n", + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ "# Create a 1×2 canvas with custom width\n", "x = np.linspace(0, 2 * np.pi, 200)\n", "canvas, (ax1, ax2) = Canvas.subplots(ncols=2, width=\"10cm\", ratio=0.3)\n", "\n", "# Left subplot: sine wave\n", - "ax1.plot(x, np.sin(x), color=\"royalblue\", label=\"sin(x)\")\n", + "ax1.plot(x, np.sin(x), color=\"royalblue\", label=\"sin(x)\", linewidth=1.5)\n", "ax1.set_title(\"sin(x)\")\n", "ax1.set_xlabel(\"x\")\n", "ax1.set_ylabel(\"amplitude\")\n", "\n", "# Right subplot: cosine wave\n", - "ax2.plot(x, np.cos(x), color=\"tomato\", label=\"cos(x)\")\n", + "ax2.plot(x, np.cos(x), color=\"tomato\", label=\"cos(x)\", linewidth=1.5)\n", "ax2.set_title(\"cos(x)\")\n", "ax2.set_xlabel(\"x\")\n", "\n", @@ -48,7 +58,7 @@ }, { "cell_type": "markdown", - "id": "2", + "id": "3", "metadata": {}, "source": [ "## 1×3 Layout: Multiple Functions\n", @@ -59,7 +69,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3", + "id": "4", "metadata": {}, "outputs": [], "source": [ @@ -69,26 +79,27 @@ "# Three different functions\n", "x = np.linspace(0, 2 * np.pi, 100)\n", "\n", - "axes[0].plot(x, np.sin(x), color=\"royalblue\")\n", + "axes[0].plot(x, np.sin(x), color=\"blue\")\n", "axes[0].set_title(\"sin(x)\")\n", "axes[0].set_xlabel(\"x\")\n", "\n", - "axes[1].plot(x, np.cos(x), color=\"tomato\")\n", + "axes[1].plot(x, np.cos(x), color=\"red\")\n", "axes[1].set_title(\"cos(x)\")\n", "axes[1].set_xlabel(\"x\")\n", "\n", - "axes[2].plot(x, np.tan(x), color=\"seagreen\")\n", + "axes[2].plot(x, np.tan(x), color=\"darkgreen\")\n", "axes[2].set_title(\"tan(x)\")\n", "axes[2].set_xlabel(\"x\")\n", "axes[2].set_ylim(-5, 5) # Limit y-range for tan\n", "\n", "canvas.suptitle(\"1 × 3 Layout: Three Trigonometric Functions\")\n", - "result = canvas.show(backend=\"tikzfigure\")" + "result = canvas.show(backend=\"tikzfigure\")\n", + "print(result)" ] }, { "cell_type": "markdown", - "id": "4", + "id": "5", "metadata": {}, "source": [ "## Important Notes\n", @@ -100,7 +111,25 @@ ] } ], - "metadata": {}, + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.3" + } + }, "nbformat": 4, "nbformat_minor": 5 } From 2b1342ef02f392b3a11d459d264e9aed445793b0 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 11 Apr 2026 08:47:22 +0200 Subject: [PATCH 3/4] Formatting --- src/maxplotlib/canvas/canvas.py | 12 ++++++++++-- src/maxplotlib/tests/test_canvas.py | 5 ++++- tutorials/tutorial_02.ipynb | 18 ++++++++++-------- tutorials/tutorial_tikzfigure_subplots.ipynb | 1 + 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/maxplotlib/canvas/canvas.py b/src/maxplotlib/canvas/canvas.py index 5fcee19..bc61b29 100644 --- a/src/maxplotlib/canvas/canvas.py +++ b/src/maxplotlib/canvas/canvas.py @@ -851,8 +851,16 @@ def plot_tikzfigure( ax = fig.subfigure_axis( xlabel=line_plot._xlabel or "", ylabel=line_plot._ylabel or "", - xlim=(line_plot._xmin, line_plot._xmax) if line_plot._xmin is not None else None, - ylim=(line_plot._ymin, line_plot._ymax) if line_plot._ymin is not None else None, + xlim=( + (line_plot._xmin, line_plot._xmax) + if line_plot._xmin is not None + else None + ), + ylim=( + (line_plot._ymin, line_plot._ymax) + if line_plot._ymin is not None + else None + ), grid=line_plot._grid, caption=line_plot._title or f"Subplot {col+1}", width=0.45, diff --git a/src/maxplotlib/tests/test_canvas.py b/src/maxplotlib/tests/test_canvas.py index 93f8641..b0cedde 100644 --- a/src/maxplotlib/tests/test_canvas.py +++ b/src/maxplotlib/tests/test_canvas.py @@ -5,6 +5,7 @@ def test(): def test_canvas_plot_tikzfigure_horizontal_subplots(): """Test that Canvas.plot_tikzfigure() works with horizontal (1×n) layouts.""" import numpy as np + from maxplotlib import Canvas # Create a 1×2 canvas @@ -33,6 +34,7 @@ def test_canvas_plot_tikzfigure_horizontal_subplots(): def test_canvas_plot_tikzfigure_three_subplots(): """Test 1×3 layout with tikzfigure backend.""" import numpy as np + from maxplotlib import Canvas x = np.linspace(0, 2 * np.pi, 50) @@ -57,9 +59,10 @@ def test_canvas_plot_tikzfigure_three_subplots(): def test_canvas_plot_tikzfigure_vertical_not_supported(): """Test that vertical layouts raise NotImplementedError.""" import numpy as np - from maxplotlib import Canvas import pytest + from maxplotlib import Canvas + x = np.linspace(0, 2 * np.pi, 50) # Create 2×1 layout (nrows=2) canvas, axes = Canvas.subplots(nrows=2, width="10cm") diff --git a/tutorials/tutorial_02.ipynb b/tutorials/tutorial_02.ipynb index 8048d11..5a00f68 100644 --- a/tutorials/tutorial_02.ipynb +++ b/tutorials/tutorial_02.ipynb @@ -42,7 +42,6 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "fig = TikzFigure()\n", "\n", "x = np.linspace(0, 360, 200)\n", @@ -51,22 +50,26 @@ "\n", "# First subfigure: sine wave\n", "ax1 = fig.subfigure_axis(\n", - " xlabel=\"x\", ylabel=\"y\",\n", - " xlim=(0, 360), ylim=(-1.5, 1.5),\n", + " xlabel=\"x\",\n", + " ylabel=\"y\",\n", + " xlim=(0, 360),\n", + " ylim=(-1.5, 1.5),\n", " grid=True,\n", " caption=\"Sine Function\",\n", - " width=0.45\n", + " width=0.45,\n", ")\n", "ax1.add_plot(x=x, y=y1, label=\"sin(x)\", color=\"red\", line_width=\"1.5pt\")\n", "ax1.set_legend(position=\"north east\")\n", "\n", "# Second subfigure: cosine wave\n", "ax2 = fig.subfigure_axis(\n", - " xlabel=\"x\", ylabel=\"y\",\n", - " xlim=(0, 360), ylim=(-1.5, 1.5),\n", + " xlabel=\"x\",\n", + " ylabel=\"y\",\n", + " xlim=(0, 360),\n", + " ylim=(-1.5, 1.5),\n", " grid=True,\n", " caption=\"Cosine Function\",\n", - " width=0.45\n", + " width=0.45,\n", ")\n", "ax2.add_plot(x=x, y=y2, label=\"cos(x)\", color=\"blue\", line_width=\"1.5pt\")\n", "ax2.set_legend(position=\"north east\")\n", @@ -89,7 +92,6 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "canvas, (ax1, ax2) = Canvas.subplots(ncols=2, width=1000, ratio=0.3)\n", "\n", "x = np.linspace(0, 2 * np.pi, 200)\n", diff --git a/tutorials/tutorial_tikzfigure_subplots.ipynb b/tutorials/tutorial_tikzfigure_subplots.ipynb index e4e816d..b12de55 100644 --- a/tutorials/tutorial_tikzfigure_subplots.ipynb +++ b/tutorials/tutorial_tikzfigure_subplots.ipynb @@ -23,6 +23,7 @@ "source": [ "from maxplotlib import Canvas\n", "import numpy as np\n", + "\n", "%load_ext autoreload\n", "%autoreload 2" ] From 9ce9bc4714af9b89c6fce2b3a032c589006e55ad Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 11 Apr 2026 09:06:52 +0200 Subject: [PATCH 4/4] bump tikzfigure[vis]>=0.2.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7128d81..aef8f35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ "matplotlib", "pint", "plotly", - "tikzfigure[vis]>=0.2.0", + "tikzfigure[vis]>=0.2.1", ] [project.optional-dependencies] test = [