2013-08-13 6 views
6

में वक्र के नीचे इंद्रधनुष रंग कैसे भरें मैं एक वक्र के नीचे इंद्रधनुष रंग भरना चाहता हूं। असल में फ़ंक्शन matplotlib.pyplot.fill_between एक एकल रंग के साथ वक्र के नीचे क्षेत्र भर सकता है।पाइथन 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() 

क्या कोई घुंडी है जो मैं इंद्रधनुष होने के लिए रंग को ट्विक कर सकता हूं? धन्यवाद।

+0

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

उत्तर

9

इस हैक करने बहुत आसान है अगर तुम आयतों की एक श्रृंखला के साथ "भरने" हैं:

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

आप आयतों छोटा करने से दांतेदार किनारों बाहर चिकनी कर सकते हैं (यानी अधिक का उपयोग बताते हैं)। इसके अतिरिक्त आप "आयत" को परिशोधित करने के लिए एक ट्रैपेज़ॉयड (या यहां तक ​​कि एक इंटरपोलेटेड बहुपद) का उपयोग कर सकते हैं।

+0

मैं समाधान आयतों की बजाय ट्रेपेज़ोइड्स का उपयोग करता है नीचे देते हैं। com/एक/30470859/213683। (मैंने इसे एक संपादन के रूप में संलग्न करने का प्रयास किया है, लेकिन अस्वीकार कर दिया गया है।) – pms

+0

@pms यह एक अच्छा जोड़ा है, लेकिन यह एक संपादन (इसलिए अस्वीकृति) का बहुत कठोर है। मुझे खुशी है कि आपने इसे स्वयं पोस्ट किया - मुझे यकीन है कि यह आसान हो जाएगा! – Hooked

4

यदि आप "रंग =" को कुछ चालाक तर्क देने का मतलब है तो मुझे डर है कि यह मेरे ज्ञान के सर्वोत्तम नहीं है। आप प्रत्येक रंग के लिए वर्गबद्ध रेखा सेट करके और ऑफसेट को बदलकर मैन्युअल रूप से ऐसा कर सकते हैं।

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

आप देखेंगे के रूप में: सही रंग के साथ उन दोनों के बीच भरने एक rainbowish यह एक मजेदार परियोजना कुछ अजगर जानने के लिए, लेकिन अगर तुम यहाँ की कोशिश की तरह नहीं लग रहा है बनाता है दे देंगे एक उदाहरण है यह इंद्रधनुष की तरह नहीं दिखता है। ऐसा इसलिए है क्योंकि हम जिस फ़ंक्शन का उपयोग कर रहे हैं वह एक वर्ग है, वास्तव में एक इंद्रधनुष विभिन्न त्रिज्या के साथ मंडलियों से बना है (यहां एक मजेदार गणित परियोजना भी है!)। यह matplotlib द्वारा भी साजिश योग्य है, मैं इसे आज़माउंगा और इसे बनाऊंगा ताकि आप इंद्रधनुष में 7 रंगों से अधिक प्लॉट कर सकें, उदाहरण के लिए पूरे स्पेक्ट्रम में प्लॉट 1000 रंगों को वास्तव में इंद्रधनुष की तरह दिखाना है!

1

यहां स्वीकृत उत्तर का एक संशोधित समाधान है जो आयताकारों के बजाय ट्रैपेज़िड्स का उपयोग करता है। http: // stackoverflow

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()