9

I'm searching for a way to draw shaded error-regions instead of error-bars in Python.

I know that there is matplotlib.pyplot.fill_between() with which you can build a workaround for the y-error but that does not include the x-uncertainty.

problem_description

Any ideas? Unfortunately I had not enough reputation to put a comment here.

Thanks in advance!


Edit

matplotlib.pyplot.fill_betweenx() leads to something like:

fill_between_problem1


Edit 2

Furthermore I suppose it to be incorrect for a complete uncertainty area. Below I draw what I suppose to be the correct shape - I hope, I'm not wrong here...

problem_sketch

import numpy as np
import matplotlib.pyplot as plt

x = np.asarray([1.0, 2.0, 3.0, 4.0])
y = np.asarray([1.0, 2.3, 3.0, 4.0])
xerr = np.asarray([0.1, 0.7, 0.1, 0.1])
yerr = np.asarray([0.1, 0.9, 1.2, 0.1])

plt.errorbar(x, y, yerr, xerr)

plt.fill_between(x, y-yerr, y+yerr, facecolor='#F0F8FF', alpha=1.0, edgecolor='none')
plt.fill_betweenx(y,x-xerr, x+xerr, facecolor='#F0F8FF', alpha=1.0, edgecolor='#8F94CC', linewidth=1, linestyle='dashed')

plt.show()
# Red lines added with inkscape.
Suuuehgi
  • 4,547
  • 3
  • 27
  • 32
  • I was thinking along those lines, too. However, don't you think that that's a rather conservative estimate? I'll try to figure out a smart way for fitting a bounding curve to a point cloud. What's your deadline? – Schorsch Jul 21 '14 at 00:03
  • I adjusted the sketch a bit to i) be more clear and ii) to correct some mistakes. I don't think that my example is conservative. Imagine completely uncorrelated points with error-values (wherever they come from). You therefore have to consider square error-regions. How does the error propagate between two points? The simplest approach would be the first-order approximation that I sketched. Don't put too many effort in that! Python has sooo incredible many modules, I can not imagine that there is nothing for such a very basic problem. – Suuuehgi Jul 21 '14 at 11:00

1 Answers1

11

I got this to work with the fill_betweenx function:

import numpy as np
import matplotlib.pyplot as plt

x = np.asarray([1.0, 2.0, 3.0, 4.0, 5.0])
y = np.asarray([1.0, 2.0, 3.0, 4.0, 5.0])
xerr = np.asarray([0.2, 0.4, 0.6, 0.8, 1.0])
yerr = np.asarray([0.1, 0.2, 0.3, 0.4, 0.5])

plt.errorbar(x, y, yerr, xerr)

plt.fill_between(x, y-yerr, y+yerr,facecolor='r',alpha=0.5)
plt.fill_betweenx(y,x-xerr,x+xerr,facecolor='b',alpha=0.5)

plt.show()  

Which results in this plot:

fill_between, fill_betweenx


EDIT

In your specific example, it may be sufficient to use:

plt.fill_between(x, y-yerr, y+yerr,facecolor='#F0F8FF',alpha=1.0,edgecolor='none')
plt.fill_betweenx(y,x-xerr, x+xerr,facecolor='#F0F8FF',alpha=1.0,edgecolor='none')

That way, you do not have edges, which would cross and give this "fold" away. Furthermore, it might generate a sufficient illusion of one error band. You'd have to use both the fill_between and fill_betweenx, though.

Schorsch
  • 7,761
  • 6
  • 39
  • 65
  • Thank you for the answer! But I see difficulties putting xerr and yerr to one uncertainty-area (same color) with borders (`edgecolor`). This would still lead to interferences. – Suuuehgi Jul 18 '14 at 13:37
  • Added a picture in the post. You can see the intersections in the upper part. – Suuuehgi Jul 18 '14 at 13:44
  • @smoneck Do I understand correctly: You are looking for one envelope, that includes all the errors in a smooth band? Or, for example in your plot for an Anstellwinkel = 0, would you like the band to touch the `y`-error? or is that part of the plot like you would want it? – Schorsch Jul 18 '14 at 13:58
  • @smoneck I'll investigate this further. – Schorsch Jul 18 '14 at 14:22
  • Thank you very much for your effort, Schorsch! But when I'm right, the uncertainty area is wrong when having overlapping xerr and yerr. I added a drawing of the problem, where I added a red line which complements the area which I suppose to be the correct one. – Suuuehgi Jul 20 '14 at 09:56