2013-08-13 10 views
6

Chcę wypełnić tęczę pod krzywą. W rzeczywistości funkcja matplotlib.pyplot.fill_between może wypełnić obszar pod krzywą pojedynczym kolorem.Jak wypełnić tęczę pod krzywą w Python matplotlib

import matplotlib.pyplot as plt 
import numpy as np 
x = np.linspace(0, 100, 50) 
y = -(x-50)**2 + 2500 
plt.plot(x,y) 
plt.fill_between(x,y, color='green') 
plt.show() 

Czy istnieje pokrętło, w którym mogę poprawić kolor tęczy? Dzięki.

+0

http://stackoverflow.com/questions/11564273/matplotlib-continuous-colormap-fill-between-two-lines – tacaswell

Odpowiedz

9

Jest to dość łatwe do włamywania jeśli chcesz „wypełnić” z serii prostokąty:

import numpy as np 
import pylab as plt 

def rect(x,y,w,h,c): 
    ax = plt.gca() 
    polygon = plt.Rectangle((x,y),w,h,color=c) 
    ax.add_patch(polygon) 

def rainbow_fill(X,Y, cmap=plt.get_cmap("jet")): 
    plt.plot(X,Y,lw=0) # Plot so the axes scale correctly 

    dx = X[1]-X[0] 
    N = float(X.size) 

    for n, (x,y) in enumerate(zip(X,Y)): 
     color = cmap(n/N) 
     rect(x,0,dx,y,color) 

# Test data  
X = np.linspace(0,10,100) 
Y = .25*X**2 - X 
rainbow_fill(X,Y) 
plt.show() 

enter image description here

można wygładzić postrzępione krawędzie poprzez prostokąty mniejsze (tj użyć więcej zwrotnica). Dodatkowo możesz użyć trapezoidu (lub nawet interpolowanego wielomianu) do dopracowania "prostokątów".

+0

załączam poniżej rozwiązanie, które wykorzystuje trapezy zamiast prostokątów: http: // stackoverflow. com/a/30470859/213683. (Próbowałem dołączyć to jako edycję, ale zostałem odrzucony.) – pms

+0

@pms Jest to miłe uzupełnienie, ale jest zbyt drastyczne w stosunku do edycji (stąd odrzucenie). Cieszę się, że napisałeś to sam - jestem pewien, że przyda się! – Hooked

4

Jeśli chodzi o podanie sprytnego argumentu "kolor =", obawiam się, że nie istnieje on zgodnie z moją najlepszą wiedzą. Można to zrobić ręcznie, ustawiając kwadratową linię dla każdego koloru i zmieniając przesunięcie. Wypełnienie między nimi poprawnych kolorów daje rainbowish To sprawia, że ​​projekt zabawa nauczyć się Pythona, ale jeśli nie masz ochoty próbuje tutaj jest przykład:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.linspace(0, 100, 50) 

y_old = -(x-50)**2 + 2500 
for delta, color in zip([2250, 2000, 1750, 1500, 1250, 1000], ["r", "orange", "g", "b", "indigo", "violet"]): 
    y_new = -(x-50)**2 + delta 
    plt.plot(x, y, "-k") 
    plt.fill_between(x, y_old, y_new, color=color) 
    y_old = y_new 

plt.ylim(0, 2500) 
plt.show() 

Example

Jak można zauważyć, to nie wygląda jak tęcza. Dzieje się tak dlatego, że funkcja, której używamy, jest kwadratowa, w rzeczywistości tęcza składa się z okręgów o różnych promieniach (jest tu także fajny projekt matematyki!). Jest to również możliwe do sparsowania przez matplotlib, spróbuję tego i sprawię, że będziesz mógł wydrukować więcej niż 7 kolorów w tęczy, np. Wydrukować 1000 kolorów obejmujących całe spektrum, aby naprawdę wyglądać jak tęcza!

1

Oto zmodyfikowane rozwiązanie zaakceptowanej odpowiedzi, która używa trapezów zamiast prostokątów.

import numpy as np 
import pylab as plt 

# a solution that uses rectangles 
def rect(x,y,w,h,c): 
    ax = plt.gca() 
    polygon = plt.Rectangle((x,y),w,h,color=c) 
    ax.add_patch(polygon) 

# a solution that uses trapezoids 
def polygon(x1,y1,x2,y2,c): 
    polygon = mplpl.Polygon([ (x1,y1), (x2,y2), (x2,0), (x1,0) ], color=c) 
    ax.add_patch(polygon) 

def rainbow_fill(X,Y, cmap=plt.get_cmap("jet")): 
    plt.plot(X,Y,lw=0) # Plot so the axes scale correctly 

    dx = X[1]-X[0] 
    N = float(X.size) 

    for n, (x,y) in enumerate(zip(X,Y)): 
     color = cmap(n/N) 
     # uncomment to use rectangles 
     # rect(x,0,dx,y,color) 
     # uncomment to use trapezoids 
     if n+1 == N: continue 
     polygon(x,y,X[n+1],Y[n+1],color) 

# Test data  
X = np.linspace(0,10,100) 
Y = .25*X**2 - X 
rainbow_fill(X,Y) 
plt.show() 
Powiązane problemy