In both the older "metpy.plots.StationPlot" and newer "metpy.plots.scattertext" in which the example gallery for plotting fronts (and my own implementation) provides a "ValueError: not enough values to unpack (expected 4, got 3)"
When running the example IPython notebook (and also in our own realtime implementation)
The error was first noticed circa mid-August 2026 with MetPy 1.6 (in code using StationPlot) and then 1.7.1 (for both StationPlot and scattertext)
The traceback errors do not go as far back into the call to scattertext or StationPlot. Error occurs in both MacOS and Ubuntu 22.04 LTS
See code from Example Gallery for Plotting Fronts:
https://unidata.github.io/MetPy/latest/examples/plots/Plotting_Surface_Analysis.html
I also attached an IPYNB and the HTML download of the IPYNB.
Error will emerge with either line example below:
scattertext(ax, x, y, field[0],
**complete_style[field], transform=ccrs.PlateCarree(), clip_on=True)
scattertext(ax, x, y, rows.strength, formatter='.0f', loc=(0, -10),
**complete_style[field], transform=ccrs.PlateCarree(), clip_on=True)
(Also occurs with earlier StationPlot examples from previous versions of the same tutorial example.
Note that the traceback error does NOT back track into the example source code.
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/backend_bases.py:2257, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2254 # we do this instead of `self.figure.draw_without_rendering`
2255 # so that we can inject the orientation
2256 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2257 self.figure.draw(renderer)
2258 else:
2259 renderer = None
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/figure.py:3282, in Figure.draw(self, renderer)
3279 # ValueError can occur when resizing a window.
3281 self.patch.draw(renderer)
-> 3282 mimage._draw_list_compositing_images(
3283 renderer, self, artists, self.suppressComposite)
3285 renderer.close_group('figure')
3286 finally:
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
131 if not_composite or not has_images:
132 for a in artists:
--> 133 a.draw(renderer)
134 else:
135 # Composite any adjacent images together
136 image_group = []
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File ~/miniforge3/lib/python3.13/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes.draw(self, renderer, **kwargs)
504 self.imshow(img, extent=extent, origin=origin,
505 transform=factory.crs, *factory_args[1:],
506 **factory_kwargs)
507 self._done_img_factory = True
--> 509 return super().draw(renderer=renderer, **kwargs)
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/axes/_base.py:3367, in _AxesBase.draw(self, renderer)
3364 if artists_rasterized:
3365 _draw_rasterized(self.get_figure(root=True), artists_rasterized, renderer)
-> 3367 mimage._draw_list_compositing_images(
3368 renderer, self, artists, self.get_figure(root=True).suppressComposite)
3370 renderer.close_group('axes')
3371 self.stale = False
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
131 if not_composite or not has_images:
132 for a in artists:
--> 133 a.draw(renderer)
134 else:
135 # Composite any adjacent images together
136 image_group = []
File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File ~/miniforge3/lib/python3.13/site-packages/metpy/plots/text.py:233, in TextCollection.draw(self, renderer)
230 _, info, _ = self._get_layout(renderer)
231 self._text = ''
--> 233 for line, _, x, y in info:
235 mtext = self if len(info) == 1 else None
236 x = x + posx
ValueError: not enough values to unpack (expected 4, got 3)
What went wrong?
In both the older "metpy.plots.StationPlot" and newer "metpy.plots.scattertext" in which the example gallery for plotting fronts (and my own implementation) provides a "ValueError: not enough values to unpack (expected 4, got 3)"
When running the example IPython notebook (and also in our own realtime implementation)
The example below shows Unidata MetPy's own example:
https://unidata.github.io/MetPy/latest/examples/plots/Plotting_Surface_Analysis.html
Jupyter Notebooks and HTML of notebooks are attached here (with documentation on all associated libraries and their versions for the error I am getting on my MacBook).
Plotting_Surface_Analysis_METPY_1p7.ipynb
Plotting_Surface_Analysis_METPY_1p7.html
The error was first noticed circa mid-August 2026 with MetPy 1.6 (in code using StationPlot) and then 1.7.1 (for both StationPlot and scattertext)
The traceback errors do not go as far back into the call to scattertext or StationPlot. Error occurs in both MacOS and Ubuntu 22.04 LTS
Operating System
MacOS
Version
1.7.1
Python Version
3.13.15 64bit [Clang 19.1.7 ]
Code to Reproduce
Errors, Traceback, and Logs
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) File ~/miniforge3/lib/python3.13/site-packages/matplotlib/backend_bases.py:2257, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs) 2254 # we do this instead of `self.figure.draw_without_rendering` 2255 # so that we can inject the orientation 2256 with getattr(renderer, "_draw_disabled", nullcontext)(): -> 2257 self.figure.draw(renderer) 2258 else: 2259 renderer = None File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs) 92 @wraps(draw) 93 def draw_wrapper(artist, renderer, *args, **kwargs): ---> 94 result = draw(artist, renderer, *args, **kwargs) 95 if renderer._rasterizing: 96 renderer.stop_rasterizing() File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer) 68 if artist.get_agg_filter() is not None: 69 renderer.start_filter() ---> 71 return draw(artist, renderer) 72 finally: 73 if artist.get_agg_filter() is not None: File ~/miniforge3/lib/python3.13/site-packages/matplotlib/figure.py:3282, in Figure.draw(self, renderer) 3279 # ValueError can occur when resizing a window. 3281 self.patch.draw(renderer) -> 3282 mimage._draw_list_compositing_images( 3283 renderer, self, artists, self.suppressComposite) 3285 renderer.close_group('figure') 3286 finally: File ~/miniforge3/lib/python3.13/site-packages/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 131 if not_composite or not has_images: 132 for a in artists: --> 133 a.draw(renderer) 134 else: 135 # Composite any adjacent images together 136 image_group = [] File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer) 68 if artist.get_agg_filter() is not None: 69 renderer.start_filter() ---> 71 return draw(artist, renderer) 72 finally: 73 if artist.get_agg_filter() is not None: File ~/miniforge3/lib/python3.13/site-packages/cartopy/mpl/geoaxes.py:509, in GeoAxes.draw(self, renderer, **kwargs) 504 self.imshow(img, extent=extent, origin=origin, 505 transform=factory.crs, *factory_args[1:], 506 **factory_kwargs) 507 self._done_img_factory = True --> 509 return super().draw(renderer=renderer, **kwargs) File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer) 68 if artist.get_agg_filter() is not None: 69 renderer.start_filter() ---> 71 return draw(artist, renderer) 72 finally: 73 if artist.get_agg_filter() is not None: File ~/miniforge3/lib/python3.13/site-packages/matplotlib/axes/_base.py:3367, in _AxesBase.draw(self, renderer) 3364 if artists_rasterized: 3365 _draw_rasterized(self.get_figure(root=True), artists_rasterized, renderer) -> 3367 mimage._draw_list_compositing_images( 3368 renderer, self, artists, self.get_figure(root=True).suppressComposite) 3370 renderer.close_group('axes') 3371 self.stale = False File ~/miniforge3/lib/python3.13/site-packages/matplotlib/image.py:133, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 131 if not_composite or not has_images: 132 for a in artists: --> 133 a.draw(renderer) 134 else: 135 # Composite any adjacent images together 136 image_group = [] File ~/miniforge3/lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer) 68 if artist.get_agg_filter() is not None: 69 renderer.start_filter() ---> 71 return draw(artist, renderer) 72 finally: 73 if artist.get_agg_filter() is not None: File ~/miniforge3/lib/python3.13/site-packages/metpy/plots/text.py:233, in TextCollection.draw(self, renderer) 230 _, info, _ = self._get_layout(renderer) 231 self._text = '' --> 233 for line, _, x, y in info: 235 mtext = self if len(info) == 1 else None 236 x = x + posx ValueError: not enough values to unpack (expected 4, got 3)