Skip to content

better input validation on fill_between #7510

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
robertsawko opened this issue Nov 24, 2016 · 14 comments
Closed

better input validation on fill_between #7510

robertsawko opened this issue Nov 24, 2016 · 14 comments
Labels
Difficulty: Easy https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues
Milestone

Comments

@robertsawko
Copy link

Hi,

So I am running on Python 3.5.2 and Matplotlib 1.5.3 and everything is installed via OS packet manager on Arch Linux. Here's the code I am having issue with:

from matplotlib.pyplot import figure
from numpy import linspace

fig = figure()
ax = fig.gca()

x = linspace(0, 1).reshape(50, 1)

ax.fill_between(x, x, -x)  # That doesn't work!
ax.fill_between(x[:, 0], x[:, 0], -x[:, 0])  # And that ugliness does!

I've already checked that this is due to where=None setting which constructrs where variable via len function. This seems inadequate in many numpy scenarios as occasionally arrays will pop up with or without second dimension. If they do have a second dimension though the where=None will force the error below.

Traceback (most recent call last):
  File "fill_between_test.py", line 11, in <module>
    ax.fill_between(x, x, -x)  # That doesn't work!
  File "/usr/lib/python3.5/site-packages/matplotlib/__init__.py", line 1819, in inner
    return func(ax, *args, **kwargs)
  File "/usr/lib/python3.5/site-packages/matplotlib/axes/_axes.py", line 4596, in fill_between
    raise ValueError("Argument dimensions are incompatible")
ValueError: Argument dimensions are incompatible

Please advise.

@tacaswell
Copy link
Member

What should fill_between do if it gets a greater than 1D array?

I think the change we should make here is to clarify that the inputs should be 1D and raise a better exception.

np.squeeze might be a better option that the above slicing.

@robertsawko
Copy link
Author

The problem originally came out when reading data from a file. The vectors were one dimenional but second dimension was fixed to 1 rather than empty. I think that case should be handled even when where=None.

@robertsawko robertsawko changed the title fill_between fill_between with non empty second dimension Nov 24, 2016
@robertsawko robertsawko changed the title fill_between with non empty second dimension fill_between with non empty second dimension Nov 24, 2016
@robertsawko robertsawko changed the title fill_between with non empty second dimension fill_between with non empty second dimension Nov 24, 2016
@tacaswell
Copy link
Member

If data.ndim != 1 it is not 1D data (in the most pedantic way).

If we start to take (N, 1) as input, then we should probably take (1, N) as valid input as well. We then would have to decide how to deal with the user providing a mix if (N,), (N, 1), and (1, N). Should we just squeeze them or is that an error? I suspect that either answer will be wrong in some contexts which is why I think it is better if mpl requires 1D inputs (that is np.array(v).ndim == 1) and leave the decisions about how to go from the application data -> what mpl needs to the application developers.

@robertsawko
Copy link
Author

Ok. I see your point. I am ok with using squeeze. Maybe then just change the error message. I was initally not aware of where parameter. The confusing thing was that all arguments I was giving explictly had agreeing dimensions.

@tacaswell tacaswell changed the title fill_between with non empty second dimension better input validation on fill_between Nov 27, 2016
@tacaswell tacaswell added this to the 2.0.1 (next bug fix release) milestone Nov 27, 2016
@tacaswell tacaswell added Difficulty: Easy https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues new-contributor-friendly labels Nov 27, 2016
@tacaswell
Copy link
Member

The exact work here:

  • validate the inputs to fill_between and fill_betweenx are 1D (because we can also take in lists, numpy arrays, and pd.Series this should probably be cbook.is_scaler(cbook.safe_first_element(inp)) to check that it is a) an iterable b) the things that come out of iteration look like scalars).
  • raise a clear error if not

@gauthamzz
Copy link

Can i try this , if it is still open ?

@tacaswell
Copy link
Member

@gauthamzz Please do! I do not think anyone is currently working on this.

@gauthamzz
Copy link

Can you tell me the names of the associated files ?

@tacaswell
Copy link
Member

Both of those methods are in lib/matplotlib/axes/_axes.py

anntzer referenced this issue Jan 18, 2017
[MRG+1] better input validation on `fill_between`
@viswanath69
Copy link

I am trying to run control chart module got below error . can you provide solution for this below error ?
ValueError Traceback (most recent call last)
in
7 cc_data = np.array(ppmdata[x_names_significant_subprocess].values.ravel().reshape(-1, 1))
8 message_cc = control_chart(x_names_significant_subprocess, directory, ccdata, target_mean, sigma,
----> 9 sub_group_size)

F:\Python Scripts\ppmBOTv07\bot\api\ppmutils.py in control_chart(MS_SP_X, directory, cc_data, target_mean, sigma, sub_group_size)
1198 chart1 = spc(target=target_mean, data=cc_data, stdev=sigma) + xmr() + mr() + rules()
1199 filename = 'CC_' + Chart_Type + datetime.datetime.now().strftime("_%Y-%m-%d-%H%M%S") + '.jpg'
-> 1200 chart1.save(os.path.join(directory,filename))
1201 plt.close()
1202 message = "Chart is saved in the Charts directory."

F:\Python Scripts\ppmBOTv07\bot\spc\spc.py in save(self, filename, **kwargs)
101 """
102 if len(self.summary) == 0:
--> 103 self.make()
104
105 nv, normp = ntest(self.datas)

F:\Python Scripts\ppmBOTv07\bot\spc\spc.py in make(self, **kwargs)
154 utl = self.t + 3 * self.sigma
155 ltl = max(self.t - 3 * self.sigma, 0)
--> 156 PlotCharts(ax, values, self.t, center, lcl, ucl, ltl, utl, title)
157
158 summary['name'] = title

F:\Python Scripts\ppmBOTv07\bot\spc\results.py in init(self, ax, values, target, center, lcl, ucl, ltl, utl, title)
27 super(PlotCharts, self).init()
28 plt.style.use('ggplot')
---> 29 self.plot_chart(ax, values, target, center, lcl, ucl, ltl, utl, title)
30
31 def plot_chart(self, ax, values, target, center, lcl, ucl, ltl, utl, title, newvalues=None):

F:\Python Scripts\ppmBOTv07\bot\spc\results.py in plot_chart(self, ax, values, target, center, lcl, ucl, ltl, utl, title, newvalues)
62
63 else:
---> 64 ax.fill_between([-0.3, num], [lcl, lcl], [ucl, ucl], facecolor='green', alpha=0.4)
65 if lcl == ltl:
66 ax.yaxis.set_ticks([lcl, target, center, ucl, utl])

F:\Anaconda\lib\site-packages\matplotlib_init_.py in inner(ax, data, *args, **kwargs)
1808 "the Matplotlib list!)" % (label_namer, func.name),
1809 RuntimeWarning, stacklevel=2)
-> 1810 return func(ax, *args, **kwargs)
1811
1812 inner.doc = _add_data_doc(inner.doc,

F:\Anaconda\lib\site-packages\matplotlib\axes_axes.py in fill_between(self, x, y1, y2, where, interpolate, step, **kwargs)
5052 if array.ndim > 1:
5053 raise ValueError('Input passed into argument "%r"' % name +
-> 5054 'is not 1-dimensional.')
5055
5056 if where is None:

ValueError: Input passed into argument "'y1'"is not 1-dimensional.

@timhoffm
Copy link
Member

What the error message says: y1 must be a 1-dimensional array. You've passed in something else.

@viswanath69
Copy link

F:\Anaconda\lib\site-packages\matplotlib\axes_axes.py in fill_between(self, x, y1, y2, where, interpolate, step, **kwargs)
5052 if array.ndim > 1:
5053 raise ValueError('Input passed into argument "%r"' % name +
-> 5054 'is not 1-dimensional.')

@viswanath69
Copy link

this was working 2 weeks back. After I installed OS due to some reason, installed Anaconda python v3.7 this error I got

@timhoffm
Copy link
Member

Please check the shape of y1 in your code and make it 1D.

I'm sorry this is popping up for you. However, this change just enforces what was implicitly assumed and explicitly documented on the data already. The former tolerance towards multi-dimensional arrays may or may not have worked properly depending on the actual data. And we don't want to risk wrong plots due to sloppy data verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Difficulty: Easy https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues
Projects
None yet
Development

No branches or pull requests

5 participants