GeezerVison is showing github.com — fill_between incorrect with log y-axis and value 0 · Issue #8623 · matplotlib/matplotlib
fill_between incorrect with log y-axis and value 0 #8623Descriptionfill_between doesn't give the result I expect if using a log y-axis and having a value of 0 in the y1 array.
Example:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
x = np.array([1, 2, 3, 4, 5])
y1 = np.array([9, 2, 8, 3, 0])
y2 = np.array([10, 10, 10, 10, 10])
plt.plot(x, y1, lw=3, color='green')
plt.plot(x, y2, lw=3, color='red')
plt.fill_between(x, y1, y2)
plt.loglog()
Actual outcome:
The polygon created by fill_between somehow connects the last and first point, resulting in a completely incorrect patch:

Expected outcome
I was expecting / hoping that the band would be filled correctly and simply clipped (i.e. the result I get when changing the last y1 value from 0 to e.g. 1e-10). In the plot, the blue fill should be between the red and green line.
Matplotlib version
This is with Matplotlib 2.0.0.
(on Macports, but I don't think that matters) Activityadded this to the This milestone has been deleted milestone on May 15, 2017dstansby commented on May 15, 2017 Confirmed on master, thanks for the code sample. dstansby commented on May 15, 2017 Slightly abstractly, y=0 is mapped to x = -infinity on a log scale, so I would expect the fill between to be clipped at the vertical line x=4 in the above example, and for the x=5, y=0 point to be ignored. cdeil commented on May 15, 2017 ContributorAuthor More actions @dstansby - Thanks for looking into the issue!
When creating the issue I forgot to mention #7371 .
I don't quite follow the discussion there, but it might be relevant to decide what to do here.
For me, any solution that doesn't have this issue that the last y1 point connects to the first y2 point would be fine.
Also, if someone else has this issue, I wanted to mention that it's possible to work around the issue using where and filtering out the non-positive y values:
where = (y_hi > 0) & (y_lo > 0) & (other possible selections you might have)
ax.fill_between(energy.value, y_lo.value, y_hi.value, where=where)
This is what I'm doing for now. cdeil commented on Jul 3, 2017 ContributorAuthor More actions @Tuan333 - Yes, indeed nonposy='clip' resolves the issue, thanks for pointing it out.
The main remaining issue is that we have to teach our users about it, because if they call plt.loglog without that option after calling the plotting functions from our package, they will still see that issue.
Close this issue?
Or is there anything that can be improved on the matplotlib side (e.g. change default behaviour)? anntzer commented on Jul 3, 2017 Probably related to #8537? dstansby commented on Jul 3, 2017 Yeah, I think finishing that PR will fix this and a few other open bugs.
I'll try and get round to it in the next couple of days.
…tacaswell commented on Jul 5, 2017 @dstansby Won't #8836 make this worse (by changing more things to mask rather than clip)? dstansby commented on Jul 6, 2017 I don't think it'll make it worse than the image in the original bug report, but it certainly doesn't fix it. modified the milestones: This milestone has been deleted, This milestone has been deleted on Sep 24, 2017afvincent commented on Nov 1, 2017 Currently, the MWE results in

with Matplotlib from master (2.1.0.post476+g30b58001f). (The issue is still present with Matplotlib 2.1 from conda)
@tacaswell @anntzer
Should we close this issue (didn't #9477 fixed it?)? tacaswell commented on Nov 1, 2017 I think this is fixed by #9477
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|