#1817·visdom

Bug: pie(), boxplot(), stem(), _surface(), and histogram2d() crash on size-1 inputs due to unconditional np.squeeze()

Author: munazzaghazali7-hashCreated Sep 10, 2026Updated Sep 10, 2026

Bug Description Five plotting methods crash with AssertionError when given size-1 inputs. The root cause is an unconditional np.squeeze() call that collapses valid (1,) arrays to 0-d scalars before the ndim assertion runs. This is the same bug class fixed for bar(), histogram(), and sunburst() in #1788.

Reproduction Steps

python
import visdom, numpy as np
viz = visdom.Visdom()

viz.pie(X=[100])
# AssertionError: X should be one-dimensional

viz.boxplot(X=[10.5])
# AssertionError: X should be one or two-dimensional

viz.stem(X=[5.0])
# AssertionError: X should be one or two-dimensional

viz._surface(X=np.ones((1, 5)))   # or surf/contour with a single row/col
# AssertionError: X should be two-dimensional

viz.histogram2d(X=[1], Y=[2])
# AssertionError: X and Y should be one-dimensional

Multi-element inputs work fine for all methods.

Expected behavior All five should render correctly with size-1 inputs, just as bar(X=[5]), histogram(X=[42]), and sunburst(values=[7]) do after #1788.

Root Cause

In py/visdom/__init__.py on the current dev branch:

Method Line Issue
pie() L4216 np.squeeze([100])() (ndim=0) → fails assert X.ndim == 1
boxplot() L3822 np.squeeze([10.5])() (ndim=0) → fails assert X.ndim == 1 or 2
stem() L4061 same as boxplot()
_surface() L3873 np.squeeze(ones((1,5))) → shape (5,) (ndim=1) → fails assert X.ndim == 2
histogram2d() L3777 np.squeeze([1])() (ndim=0) → fails assert X.ndim == 1

Screenshots If applicable, add screenshots to help explain your problem.

Client logs: N/A — crashes server-side before reaching the frontend.

Server logs: AssertionError: X should be one-dimensional AssertionError: X should be one or two-dimensional AssertionError: X should be two-dimensional AssertionError: X and Y should be one-dimensional

Additional Context

Suggested fix:

For pie(), boxplot(), stem(), histogram2d() — same pattern as #1788:

python
X = np.atleast_1d(np.squeeze(X))

For _surface() — needs a different guard since valid inputs are 2D matrices (e.g. ones((1,5))), so np.atleast_1d would incorrectly collapse them:

python
if X.ndim > 2:
    X = np.squeeze(X)
assert X.ndim == 2, "X should be two-dimensional"

I'll submit a PR for this.