Rysuj yerr / xerr jako zacieniony region, a nie słupki błędów

Odpowiedzi:

158

Ignorując płynną interpolację między punktami na przykładowym wykresie (która wymagałaby ręcznej interpolacji lub po prostu miała wyższą rozdzielczość danych), możesz użyć pyplot.fill_between():

from matplotlib import pyplot as plt
import numpy as np

x = np.linspace(0, 30, 30)
y = np.sin(x/6*np.pi)
error = np.random.normal(0.1, 0.02, size=y.shape)
y += np.random.normal(0, 0.1, size=y.shape)

plt.plot(x, y, 'k-')
plt.fill_between(x, y-error, y+error)
plt.show()

wprowadź opis obrazu tutaj

Zobacz także przykłady matplotlib .

Gabriel
źródło
1
Idealny. Tak, nie chciałem dołączyć przykładu z wygładzonymi liniami.
Austin Richardson
Masz jakiś pomysł, jak sprawić, by ten pokaz był zacieniony zamiast zacienionego paska? Moim pierwszym odruchem było nadużycie, lwale wydaje się, że nie używa tych samych jednostek co topory.
Benjamin Bannier
@BenjaminBannier Nie jestem do końca pewien, co masz na myśli. Brzmi to tak, jakbyś chciał rysować prostokąt w każdym punkcie, jego wysokość jest taka sama jak pasek błędu, a szerokość powinna być taka, aby łączyły (dotykały) sąsiednie pola. Czy to jest poprawne?
1
@EL_DON Masz na myśli, że chciałbyś otrzymać legendę z czarną linią + niebieskim paskiem, a tekst byłby podobny do „data + 1 sigma region błędu”?
1
@Allan, jeśli jedyne słupki błędów, które masz, są poziome, prawdopodobnie powinieneś odwrócić osie twojego rzeczywistego problemu (a tym samym również figurę). Zwykle zmienną niezależną jest zmienna bez (lub z bardzo małymi) słupkami błędu. Możesz oszukiwać, zamieniając zmienne danych, aw matplotlib również zamieniając osie.
134

Jest to w zasadzie ta sama odpowiedź udzielona przez Everta , ale rozszerzona o kilka fajnych opcjifill_between

wprowadź opis obrazu tutaj

from matplotlib import pyplot as pl
import numpy as np

pl.clf()
pl.hold(1)

x = np.linspace(0, 30, 100)
y = np.sin(x) * 0.5
pl.plot(x, y, '-k')


x = np.linspace(0, 30, 30)
y = np.sin(x/6*np.pi)
error = np.random.normal(0.1, 0.02, size=y.shape) +.1
y += np.random.normal(0, 0.1, size=y.shape)

pl.plot(x, y, 'k', color='#CC4F1B')
pl.fill_between(x, y-error, y+error,
    alpha=0.5, edgecolor='#CC4F1B', facecolor='#FF9848')

y = np.cos(x/6*np.pi)    
error = np.random.rand(len(y)) * 0.5
y += np.random.normal(0, 0.1, size=y.shape)
pl.plot(x, y, 'k', color='#1B2ACC')
pl.fill_between(x, y-error, y+error,
    alpha=0.2, edgecolor='#1B2ACC', facecolor='#089FFF',
    linewidth=4, linestyle='dashdot', antialiased=True)



y = np.cos(x/6*np.pi)  + np.sin(x/3*np.pi)  
error = np.random.rand(len(y)) * 0.5
y += np.random.normal(0, 0.1, size=y.shape)
pl.plot(x, y, 'k', color='#3F7F4C')
pl.fill_between(x, y-error, y+error,
    alpha=1, edgecolor='#3F7F4C', facecolor='#7EFF99',
    linewidth=0)



pl.show()
Boris Gorelik
źródło
1
Nieco lepsze rozwiązanie: stackoverflow.com/questions/43064524/…
Shital Shah