Skip to content

cbook._reshape_2D flattens ndarray with 2 dims (rectangular ndarray) #8092

Open
@lcapalleja

Description

@lcapalleja

Bug report

boxplot throwing an error (below) when x is an ndarray with len(x.shape)==2 (I.E. when x is rectangular).

ValueError: List of boxplot statistics and 'positions' values must have same the length

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

a = np.array([np.array([1, 2, 3, 4]), np.array([3, 2, 7, 4]), np.array([3, 9, 3, 1, 6])]) 
b = np.array([np.array([1, 2, 3, 4]), np.array([3, 2, 7, 4]), np.array([3, 9, 3, 1])]) 

# Ragged ndarray works correctly
plt.boxplot(x=a, positions=range(len(a)))

# Rectangular ndarray throws error (above)
plt.boxplot(x=b, positions=range(len(b)))

Matplotlib version

  • matplotlib 1.5.3 np111py35_0
  • python 3.5.2
  • Windows Server 2012 R2 Standard
  • conda installation

Possible cause

I believe the issue is in cbook._reshape_2D in the line below. I am not sure why that logic is in place but assume it is for good reason.

X = [X[:, i] for i in xrange(ncols)]

Got there by looking in:

  1. _axes.boxplot
  2. _axes.bxp
  3. cbook.boxplot_stats

reference _reshape_2D:

def _reshape_2D(X):
    """
    Converts a non-empty list or an ndarray of two or fewer dimensions
    into a list of iterable objects so that in

        for v in _reshape_2D(X):

    v is iterable and can be used to instantiate a 1D array.
    """
    if hasattr(X, 'shape'):
        # one item
        if len(X.shape) == 1:
            if hasattr(X[0], 'shape'):
                X = list(X)
            else:
                X = [X, ]

        # several items
        elif len(X.shape) == 2:
            nrows, ncols = X.shape
            if nrows == 1:
                X = [X]
            elif ncols == 1:
                X = [X.ravel()]
            else:
                X = [X[:, i] for i in xrange(ncols)]
        else:
            raise ValueError("input `X` must have 2 or fewer dimensions")

    if not hasattr(X[0], '__len__'):
        X = [X]
    else:
        X = [np.ravel(x) for x in X]

    return X

Current Workaround
Converting the ndarray to a list of lists. The necessity for this workaround doesn't really make sense especially since the plotting works fine with a ragged/non-rectangular ndarray but does not work with a rectangular ndarray.

Metadata

Metadata

Assignees

No one assigned

    Labels

    API: consistencykeepItems to be ignored by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions