From b468641b3904c673ab4e362ba09700b9c399682a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Sat, 5 Jul 2025 15:32:40 +0000 Subject: [PATCH 01/14] Add data parameters to plot function in axes3d + add test for data plot in axes3d --- lib/mpl_toolkits/mplot3d/axes3d.py | 18 ++++++++++++++---- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 55b204022fb9..a2dd4678022f 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1963,7 +1963,7 @@ def text(self, x, y, z, s, zdir=None, *, axlim_clip=False, **kwargs): text3D = text text2D = Axes.text - def plot(self, xs, ys, *args, zdir='z', axlim_clip=False, **kwargs): + def plot(self, xs, ys, zs, fmt=None, *, zdir='z', axlim_clip=False, data=None, **kwargs): # noqa: E501 """ Plot 2D or 3D data. @@ -1982,15 +1982,26 @@ def plot(self, xs, ys, *args, zdir='z', axlim_clip=False, **kwargs): Whether to hide data that is outside the axes view limits. .. versionadded:: 3.10 + data : indexable object, optional + An object with labelled data. If given, provide the label names to + plot in *x*, *y* and *z*. **kwargs Other arguments are forwarded to `matplotlib.axes.Axes.plot`. """ had_data = self.has_data() - + # Use data parameter like 2d plot. + if data: + xs=data[xs] + ys=data[ys] + if 'zs' in kwargs: + zs=kwargs.pop('zs') + else: + zs,*args= args + zs=data[zs] # `zs` can be passed positionally or as keyword; checking whether # args[0] is a string matches the behavior of 2D `plot` (via # `_process_plot_var_args`). - if args and not isinstance(args[0], str): + elif args and not isinstance(args[0], str): zs, *args = args if 'zs' in kwargs: raise TypeError("plot() for multiple values for argument 'zs'") @@ -1998,7 +2009,6 @@ def plot(self, xs, ys, *args, zdir='z', axlim_clip=False, **kwargs): zs = kwargs.pop('zs', 0) xs, ys, zs = cbook._broadcast_with_masks(xs, ys, zs) - lines = super().plot(xs, ys, *args, **kwargs) for line in lines: art3d.line_2d_to_3d(line, zs=zs, zdir=zdir, axlim_clip=axlim_clip) diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index cd45c8e33a6f..b5979f57a5f9 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -350,6 +350,12 @@ def test_plot_scalar(fig_test, fig_ref): ax2 = fig_ref.add_subplot(projection='3d') ax2.plot(1, 1, "o") +@check_figures_equal() +def test_plot_data(fig_test, fig_ref): + ax1 = fig_test.add_subplot(projection='3d') + ax1.plot('x','y','r',data=dict(x=[1,2,3],y=[4,5,6],r=[7,8,9])) + ax2 = fig_ref.add_subplot(projection='3d') + ax2.plot([1,2,3],[4,5,6],[7,8,9]) def test_invalid_line_data(): with pytest.raises(RuntimeError, match='x must be'): From 58a7d2192f47542c82f49735e071fdd04ea0dfdc Mon Sep 17 00:00:00 2001 From: Vagner Messias Date: Sun, 6 Jul 2025 11:47:00 -0300 Subject: [PATCH 02/14] Test Handling --- lib/mpl_toolkits/mplot3d/axes3d.py | 90 +++++++++---------- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 10 ++- 2 files changed, 47 insertions(+), 53 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index a2dd4678022f..c05bf668717d 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1963,59 +1963,51 @@ def text(self, x, y, z, s, zdir=None, *, axlim_clip=False, **kwargs): text3D = text text2D = Axes.text - def plot(self, xs, ys, zs, fmt=None, *, zdir='z', axlim_clip=False, data=None, **kwargs): # noqa: E501 - """ - Plot 2D or 3D data. - Parameters - ---------- - xs : 1D array-like - x coordinates of vertices. - ys : 1D array-like - y coordinates of vertices. - zs : float or 1D array-like - z coordinates of vertices; either one for all points or one for - each point. - zdir : {'x', 'y', 'z'}, default: 'z' - When plotting 2D data, the direction to use as z. - axlim_clip : bool, default: False - Whether to hide data that is outside the axes view limits. +def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, data=None, **kwargs): + """ + Plot 2D or 3D data. + + Parameters + ---------- + xs : 1D array-like or label + x coordinates of vertices, or a column label if `data` is given. + ys : 1D array-like or label + y coordinates of vertices, or a column label if `data` is given. + zs : float or 1D array-like or label, default: 0 + z coordinates of vertices, or a column label if `data` is given. + fmt : str, optional + A format string, e.g., 'ro' for red circles. + zdir : {'x', 'y', 'z'}, default: 'z' + When plotting 2D data, the direction to use as z. + axlim_clip : bool, default: False + Whether to hide data that is outside the axes view limits. + data : indexable object, optional + If given, provides labeled data to plot. + **kwargs + Other arguments forwarded to `Axes.plot`. + """ + had_data = self.has_data() - .. versionadded:: 3.10 - data : indexable object, optional - An object with labelled data. If given, provide the label names to - plot in *x*, *y* and *z*. - **kwargs - Other arguments are forwarded to `matplotlib.axes.Axes.plot`. - """ - had_data = self.has_data() - # Use data parameter like 2d plot. - if data: - xs=data[xs] - ys=data[ys] - if 'zs' in kwargs: - zs=kwargs.pop('zs') - else: - zs,*args= args - zs=data[zs] - # `zs` can be passed positionally or as keyword; checking whether - # args[0] is a string matches the behavior of 2D `plot` (via - # `_process_plot_var_args`). - elif args and not isinstance(args[0], str): - zs, *args = args - if 'zs' in kwargs: - raise TypeError("plot() for multiple values for argument 'zs'") - else: - zs = kwargs.pop('zs', 0) + # Resolve string labels using data, if given + if data is not None: + xs = data[xs] if isinstance(xs, str) else xs + ys = data[ys] if isinstance(ys, str) else ys + zs = data[zs] if isinstance(zs, str) else zs - xs, ys, zs = cbook._broadcast_with_masks(xs, ys, zs) - lines = super().plot(xs, ys, *args, **kwargs) - for line in lines: - art3d.line_2d_to_3d(line, zs=zs, zdir=zdir, axlim_clip=axlim_clip) + xs, ys, zs = cbook._broadcast_with_masks(xs, ys, zs) - xs, ys, zs = art3d.juggle_axes(xs, ys, zs, zdir) - self.auto_scale_xyz(xs, ys, zs, had_data) - return lines + if fmt is not None: + lines = super().plot(xs, ys, fmt, **kwargs) + else: + lines = super().plot(xs, ys, **kwargs) + + for line in lines: + art3d.line_2d_to_3d(line, zs=zs, zdir=zdir, axlim_clip=axlim_clip) + + xs, ys, zs = art3d.juggle_axes(xs, ys, zs, zdir) + self.auto_scale_xyz(xs, ys, zs, had_data) + return lines plot3D = plot diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index b5979f57a5f9..5400f16dd62d 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -346,16 +346,18 @@ def test_lines3d(): @check_figures_equal() def test_plot_scalar(fig_test, fig_ref): ax1 = fig_test.add_subplot(projection='3d') - ax1.plot([1], [1], "o") + ax1.plot([1], [1], [1], "o") ax2 = fig_ref.add_subplot(projection='3d') - ax2.plot(1, 1, "o") + ax2.plot(1, 1, 1, "o") + @check_figures_equal() def test_plot_data(fig_test, fig_ref): ax1 = fig_test.add_subplot(projection='3d') - ax1.plot('x','y','r',data=dict(x=[1,2,3],y=[4,5,6],r=[7,8,9])) + ax1.plot('x', 'y', 'z', fmt='r', data=dict(x=[1, 2, 3], y=[4, 5, 6], z=[7, 8, 9])) ax2 = fig_ref.add_subplot(projection='3d') - ax2.plot([1,2,3],[4,5,6],[7,8,9]) + ax2.plot([1, 2, 3], [4, 5, 6], [7, 8, 9], 'r') + def test_invalid_line_data(): with pytest.raises(RuntimeError, match='x must be'): From b2f97141ef87d07420391eae8c2f0c94a9213332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:45:38 +0000 Subject: [PATCH 03/14] Refactor test_plot_data to use explicit lists for coordinates --- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index b5979f57a5f9..4e45861900d4 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -353,9 +353,9 @@ def test_plot_scalar(fig_test, fig_ref): @check_figures_equal() def test_plot_data(fig_test, fig_ref): ax1 = fig_test.add_subplot(projection='3d') - ax1.plot('x','y','r',data=dict(x=[1,2,3],y=[4,5,6],r=[7,8,9])) + ax1.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) ax2 = fig_ref.add_subplot(projection='3d') - ax2.plot([1,2,3],[4,5,6],[7,8,9]) + ax2.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) def test_invalid_line_data(): with pytest.raises(RuntimeError, match='x must be'): From ef4216cc981ab5a2d27614e03dac5c90b4b37ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:48:05 +0000 Subject: [PATCH 04/14] Refactor test_plot_data to use explicit lists for coordinates --- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index ce2ad1d5f55e..e55f2a7abbcd 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -354,9 +354,9 @@ def test_plot_scalar(fig_test, fig_ref): @check_figures_equal() def test_plot_data(fig_test, fig_ref): ax1 = fig_test.add_subplot(projection='3d') - ax1.plot('x','y','r',data=dict(x=[1,2,3],y=[4,5,6],r=[7,8,9])) + ax1.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) ax2 = fig_ref.add_subplot(projection='3d') - ax2.plot([1,2,3],[4,5,6],[7,8,9]) + ax2.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) def test_invalid_line_data(): with pytest.raises(RuntimeError, match='x must be'): From 809e80483ac7b10891c66957144ee45ad72c7da3 Mon Sep 17 00:00:00 2001 From: Vagner Messias Date: Mon, 7 Jul 2025 12:05:26 -0300 Subject: [PATCH 05/14] Test adjustments Co-Authored-By: Bruno Wolf Povoa --- lib/mpl_toolkits/mplot3d/axes3d.py | 81 ++++++++++--------- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 1 + .../mplot3d/tests/test_legend3d.py | 4 +- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index c05bf668717d..53b1451e400b 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1964,50 +1964,51 @@ def text(self, x, y, z, s, zdir=None, *, axlim_clip=False, **kwargs): text2D = Axes.text -def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, data=None, **kwargs): - """ - Plot 2D or 3D data. - - Parameters - ---------- - xs : 1D array-like or label - x coordinates of vertices, or a column label if `data` is given. - ys : 1D array-like or label - y coordinates of vertices, or a column label if `data` is given. - zs : float or 1D array-like or label, default: 0 - z coordinates of vertices, or a column label if `data` is given. - fmt : str, optional - A format string, e.g., 'ro' for red circles. - zdir : {'x', 'y', 'z'}, default: 'z' - When plotting 2D data, the direction to use as z. - axlim_clip : bool, default: False - Whether to hide data that is outside the axes view limits. - data : indexable object, optional - If given, provides labeled data to plot. - **kwargs - Other arguments forwarded to `Axes.plot`. - """ - had_data = self.has_data() + def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, + data=None, **kwargs): + """ + Plot 2D or 3D data. + + Parameters + ---------- + xs : 1D array-like or label + x coordinates of vertices, or a column label if `data` is given. + ys : 1D array-like or label + y coordinates of vertices, or a column label if `data` is given. + zs : float or 1D array-like or label, default: 0 + z coordinates of vertices, or a column label if `data` is given. + fmt : str, optional + A format string, e.g., 'ro' for red circles. + zdir : {'x', 'y', 'z'}, default: 'z' + When plotting 2D data, the direction to use as z. + axlim_clip : bool, default: False + Whether to hide data that is outside the axes view limits. + data : indexable object, optional + If given, provides labeled data to plot. + **kwargs + Other arguments forwarded to `Axes.plot`. + """ + had_data = self.has_data() - # Resolve string labels using data, if given - if data is not None: - xs = data[xs] if isinstance(xs, str) else xs - ys = data[ys] if isinstance(ys, str) else ys - zs = data[zs] if isinstance(zs, str) else zs + # Resolve string labels using data, if given + if data is not None: + xs = data[xs] if isinstance(xs, str) else xs + ys = data[ys] if isinstance(ys, str) else ys + zs = data[zs] if isinstance(zs, str) else zs - xs, ys, zs = cbook._broadcast_with_masks(xs, ys, zs) + xs, ys, zs = cbook._broadcast_with_masks(xs, ys, zs) - if fmt is not None: - lines = super().plot(xs, ys, fmt, **kwargs) - else: - lines = super().plot(xs, ys, **kwargs) + if fmt is not None: + lines = super().plot(xs, ys, fmt, **kwargs) + else: + lines = super().plot(xs, ys, **kwargs) - for line in lines: - art3d.line_2d_to_3d(line, zs=zs, zdir=zdir, axlim_clip=axlim_clip) + for line in lines: + art3d.line_2d_to_3d(line, zs=zs, zdir=zdir, axlim_clip=axlim_clip) - xs, ys, zs = art3d.juggle_axes(xs, ys, zs, zdir) - self.auto_scale_xyz(xs, ys, zs, had_data) - return lines + xs, ys, zs = art3d.juggle_axes(xs, ys, zs, zdir) + self.auto_scale_xyz(xs, ys, zs, had_data) + return lines plot3D = plot @@ -4044,7 +4045,7 @@ def stem(self, x, y, z, *, linefmt='C0-', markerfmt='C0o', basefmt='C3-', linestyle = mpl._val_or_rc(linestyle, 'lines.linestyle') # Plot everything in required order. - baseline, = self.plot(basex, basey, basefmt, zs=bottom, + baseline, = self.plot(basex, basey, zs=bottom, fmt=basefmt, zdir=orientation, label='_nolegend_') stemlines = art3d.Line3DCollection( lines, linestyles=linestyle, colors=linecolor, label='_nolegend_', diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index e55f2a7abbcd..57031173cb64 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -358,6 +358,7 @@ def test_plot_data(fig_test, fig_ref): ax2 = fig_ref.add_subplot(projection='3d') ax2.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) + def test_invalid_line_data(): with pytest.raises(RuntimeError, match='x must be'): art3d.Line3D(0, [], []) diff --git a/lib/mpl_toolkits/mplot3d/tests/test_legend3d.py b/lib/mpl_toolkits/mplot3d/tests/test_legend3d.py index 7fd676df1e31..af50d72185b7 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_legend3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_legend3d.py @@ -13,8 +13,8 @@ def test_legend_plot(): fig, ax = plt.subplots(subplot_kw=dict(projection='3d')) x = np.arange(10) - ax.plot(x, 5 - x, 'o', zdir='y', label='z=1') - ax.plot(x, x - 5, 'o', zdir='y', label='z=-1') + ax.plot(x, 5 - x, 0, fmt='o', zdir='y', label='z=1') + ax.plot(x, x - 5, 0, fmt='o', zdir='y', label='z=-1') ax.legend() From c451c29e67789412187151233548382f65c47aca Mon Sep 17 00:00:00 2001 From: Vagner Messias Date: Mon, 7 Jul 2025 12:18:01 -0300 Subject: [PATCH 06/14] new test checking --- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index 57031173cb64..4dcbdf1303bf 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -351,12 +351,6 @@ def test_plot_scalar(fig_test, fig_ref): ax2.plot(1, 1, 1, "o") -@check_figures_equal() -def test_plot_data(fig_test, fig_ref): - ax1 = fig_test.add_subplot(projection='3d') - ax1.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) - ax2 = fig_ref.add_subplot(projection='3d') - ax2.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) def test_invalid_line_data(): From edb05b713411f7abe1194334593b59679be5b3f1 Mon Sep 17 00:00:00 2001 From: Vagner Messias Date: Mon, 7 Jul 2025 13:19:02 -0300 Subject: [PATCH 07/14] CI Fix --- lib/mpl_toolkits/mplot3d/axes3d.py | 2 +- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 53b1451e400b..941aac5cc578 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1986,7 +1986,7 @@ def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, data : indexable object, optional If given, provides labeled data to plot. **kwargs - Other arguments forwarded to `Axes.plot`. + Other arguments forwarded to 'Axes.plot'. """ had_data = self.has_data() diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index 4dcbdf1303bf..c08c4d63d94c 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -352,7 +352,6 @@ def test_plot_scalar(fig_test, fig_ref): - def test_invalid_line_data(): with pytest.raises(RuntimeError, match='x must be'): art3d.Line3D(0, [], []) From 93469e75d9d1d10e76e97c1da4a3c1fb707e7367 Mon Sep 17 00:00:00 2001 From: Vagner Messias Date: Mon, 7 Jul 2025 13:36:29 -0300 Subject: [PATCH 08/14] CI docstring fix --- lib/mpl_toolkits/mplot3d/axes3d.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 941aac5cc578..91f078bed531 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1972,11 +1972,11 @@ def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, Parameters ---------- xs : 1D array-like or label - x coordinates of vertices, or a column label if `data` is given. + x coordinates of vertices, or a column label if 'data' is given. ys : 1D array-like or label - y coordinates of vertices, or a column label if `data` is given. + y coordinates of vertices, or a column label if 'data' is given. zs : float or 1D array-like or label, default: 0 - z coordinates of vertices, or a column label if `data` is given. + z coordinates of vertices, or a column label if 'data' is given. fmt : str, optional A format string, e.g., 'ro' for red circles. zdir : {'x', 'y', 'z'}, default: 'z' From e75e13bc7d288009ae4142c2ac808c5db97aa7b4 Mon Sep 17 00:00:00 2001 From: Bruno Wolf Povoa Date: Mon, 7 Jul 2025 17:04:28 +0000 Subject: [PATCH 09/14] implemented test plot data --- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index c08c4d63d94c..57031173cb64 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -351,6 +351,13 @@ def test_plot_scalar(fig_test, fig_ref): ax2.plot(1, 1, 1, "o") +@check_figures_equal() +def test_plot_data(fig_test, fig_ref): + ax1 = fig_test.add_subplot(projection='3d') + ax1.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) + ax2 = fig_ref.add_subplot(projection='3d') + ax2.plot([1, 2, 3], [4, 5, 6], [7, 8, 9]) + def test_invalid_line_data(): with pytest.raises(RuntimeError, match='x must be'): From c0b2bf7882da685db2d9a9a9f96602964c2dcafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Tue, 8 Jul 2025 22:14:28 +0000 Subject: [PATCH 10/14] Adding API change notes to plot method in Axes3D class --- lib/mpl_toolkits/mplot3d/axes3d.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 91f078bed531..af63fd306a51 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1969,6 +1969,24 @@ def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, """ Plot 2D or 3D data. + .. versionchanged:: 3.10 + + .. api-changed:: 3.10 + + The signature of ``Axes3D.plot`` was changed to require all positional data + arguments (xs, ys, zs) and the format string (fmt) to be passed + positionally.All other arguments, including ``zdir``, ``axlim_clip``, + and ``data``, must be passed as keyword arguments. + + This is a formal API incompatibility for edge cases such as + ``plot(xs, ys, 'ro', zs=zs)``, which is no longer supported. Instead, + use ``plot(xs, ys, zs, 'ro')`` or ``plot(xs, ys, zs=zs, fmt='ro')``. + + This change brings the 3D API in line with the 2D API and avoids + ambiguity in argument parsing.Other similar edge cases where a style + string is followed by a keyword data argument are + also now formally incompatible. + Parameters ---------- xs : 1D array-like or label From 688e153da68547436d1f03a1bdf52b8e01ba1ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Wed, 9 Jul 2025 14:13:36 +0000 Subject: [PATCH 11/14] Using the preprocess data decorator fot the axes3d method --- lib/mpl_toolkits/mplot3d/axes3d.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index af63fd306a51..7b218cb7b028 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1963,7 +1963,7 @@ def text(self, x, y, z, s, zdir=None, *, axlim_clip=False, **kwargs): text3D = text text2D = Axes.text - + @_preprocess_data(replace_names=['xs', 'ys', 'zs']) def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, data=None, **kwargs): """ @@ -2008,12 +2008,6 @@ def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, """ had_data = self.has_data() - # Resolve string labels using data, if given - if data is not None: - xs = data[xs] if isinstance(xs, str) else xs - ys = data[ys] if isinstance(ys, str) else ys - zs = data[zs] if isinstance(zs, str) else zs - xs, ys, zs = cbook._broadcast_with_masks(xs, ys, zs) if fmt is not None: From 34cd222f6ec115270393b1145d3aa9544eb1d459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Wed, 9 Jul 2025 14:31:46 +0000 Subject: [PATCH 12/14] Refactor plot method in Axes3D class to simplify parameter handling --- lib/mpl_toolkits/mplot3d/axes3d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 7b218cb7b028..11495427dd70 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1965,7 +1965,7 @@ def text(self, x, y, z, s, zdir=None, *, axlim_clip=False, **kwargs): @_preprocess_data(replace_names=['xs', 'ys', 'zs']) def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, - data=None, **kwargs): + **kwargs): """ Plot 2D or 3D data. From 98b9c66a773562cba668b144d9242407c5adb7d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Thu, 10 Jul 2025 01:41:28 +0000 Subject: [PATCH 13/14] Refactor plot doc + test with implicit zs=0 --- lib/mpl_toolkits/mplot3d/axes3d.py | 31 ++++--------------- lib/mpl_toolkits/mplot3d/tests/test_axes3d.py | 2 ++ 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 11495427dd70..fb5c8fadb60f 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1964,8 +1964,7 @@ def text(self, x, y, z, s, zdir=None, *, axlim_clip=False, **kwargs): text2D = Axes.text @_preprocess_data(replace_names=['xs', 'ys', 'zs']) - def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, - **kwargs): + def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, **kwargs): """ Plot 2D or 3D data. @@ -1973,38 +1972,20 @@ def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, .. api-changed:: 3.10 - The signature of ``Axes3D.plot`` was changed to require all positional data - arguments (xs, ys, zs) and the format string (fmt) to be passed - positionally.All other arguments, including ``zdir``, ``axlim_clip``, - and ``data``, must be passed as keyword arguments. + The signature was changed to make the parameters *zs* and *fmt* explicit. - This is a formal API incompatibility for edge cases such as - ``plot(xs, ys, 'ro', zs=zs)``, which is no longer supported. Instead, - use ``plot(xs, ys, zs, 'ro')`` or ``plot(xs, ys, zs=zs, fmt='ro')``. - - This change brings the 3D API in line with the 2D API and avoids - ambiguity in argument parsing.Other similar edge cases where a style - string is followed by a keyword data argument are - also now formally incompatible. + The unconventional but previously valid call signature + ``plot(xs, ys, 'ro', zs=zs)`` is no longer supported. Parameters ---------- - xs : 1D array-like or label - x coordinates of vertices, or a column label if 'data' is given. - ys : 1D array-like or label - y coordinates of vertices, or a column label if 'data' is given. - zs : float or 1D array-like or label, default: 0 - z coordinates of vertices, or a column label if 'data' is given. - fmt : str, optional - A format string, e.g., 'ro' for red circles. zdir : {'x', 'y', 'z'}, default: 'z' When plotting 2D data, the direction to use as z. axlim_clip : bool, default: False Whether to hide data that is outside the axes view limits. - data : indexable object, optional - If given, provides labeled data to plot. + DATA_PARAMETER_PLACEHOLDER **kwargs - Other arguments forwarded to 'Axes.plot'. + Other arguments are forwarded to 'Axes.plot'. """ had_data = self.has_data() diff --git a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py index 57031173cb64..b2b33db164a0 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_axes3d.py @@ -347,8 +347,10 @@ def test_lines3d(): def test_plot_scalar(fig_test, fig_ref): ax1 = fig_test.add_subplot(projection='3d') ax1.plot([1], [1], [1], "o") + ax1.plot([2], [2], "o") ax2 = fig_ref.add_subplot(projection='3d') ax2.plot(1, 1, 1, "o") + ax2.plot(2, 2, 0, "o") @check_figures_equal() From 0c04c8abe5e6016e3c50163f57f0c377f4cc8280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=ADvia=20Lutz?= <108961867+livlutz@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:53:18 +0000 Subject: [PATCH 14/14] Update Axes3D.plot docstring to clarify parameter types and signature changes --- lib/mpl_toolkits/mplot3d/axes3d.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index fb5c8fadb60f..620f35a7fd3d 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1969,13 +1969,17 @@ def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, **kwargs): Plot 2D or 3D data. .. versionchanged:: 3.10 - - .. api-changed:: 3.10 - - The signature was changed to make the parameters *zs* and *fmt* explicit. - - The unconventional but previously valid call signature - ``plot(xs, ys, 'ro', zs=zs)`` is no longer supported. + xs : 1D array-like + x coordinates of vertices. + ys : 1D array-like + y coordinates of vertices. + zs : float or 1D array-like + z coordinates of vertices; either one for all points or one for + each point. + The signature was changed to make the parameters *zs* and *fmt* explicit. + + The unconventional but previously valid call signature + ``plot(xs, ys, 'ro', zs=zs)`` is no longer supported. Parameters ---------- @@ -1983,7 +1987,8 @@ def plot(self, xs, ys, zs=0, fmt=None, *, zdir='z', axlim_clip=False, **kwargs): When plotting 2D data, the direction to use as z. axlim_clip : bool, default: False Whether to hide data that is outside the axes view limits. - DATA_PARAMETER_PLACEHOLDER + data : indexable object, optional + DATA_PARAMETER_PLACEHOLDER **kwargs Other arguments are forwarded to 'Axes.plot'. """ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy