简体   繁体   English

如何在 Python matplotlib 中的曲线下填充彩虹色

[英]How to fill rainbow color under a curve in Python matplotlib

I want to fill rainbow color under a curve.我想在曲线下填充彩虹色。 Actually the function matplotlib.pyplot.fill_between can fill area under a curve with a single color.实际上函数 matplotlib.pyplot.fill_between 可以用单一颜色填充曲线下的区域。

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

Is there a knob I can tweak the color to be rainbow?有没有旋钮可以把颜色调成彩虹色? Thanks.谢谢。

This is pretty easy to hack if you want "fill" with a series of rectangles:如果您想用一系列矩形“填充”,这很容易破解:

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

在此处输入图片说明

You can smooth out the jagged edges by making the rectangles smaller (ie use more points).您可以通过使矩形变小(即使用更多点)来平滑锯齿状边缘。 Additionally you could use a trapezoid (or even an interpolated polynomial) to refine the "rectangles".此外,您可以使用梯形(甚至内插多项式)来细化“矩形”。

If you mean giving some clever argument to "color=" I'm afraid this doesn't exist to the best of my knowledge.如果你的意思是给“颜色=”一些聪明的论据,恐怕据我所知,这并不存在。 You could do this manually by setting a quadratic line for each color and varying the offset.您可以通过为每种颜色设置一条二次线并改变偏移量来手动执行此操作。 Filling between them with the correct colors will give a rainbowish This makes a fun project to learn some python but if you don't feel like trying here is an example:用正确的颜色填充它们之间会产生彩虹色这是一个有趣的项目来学习一些 python 但如果你不想尝试这里是一个例子:

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

例子

As you will notice this does not look like a rainbow.正如您会注意到的,这看起来不像彩虹。 This is because the function we are using is a quadratic, in actual fact a rainbow is made of circles with different radii (there is also a fun maths project here!).这是因为我们使用的函数是二次函数,实际上彩虹是由不同半径的圆组成的(这里还有一个有趣的数学项目!)。 This is also plotable by matplotlib, I would try this and make it so you can plot more than the 7 colors in the rainbow eg plot 1000 colors spanning the entire spectrum to make it really look like a rainbow!这也可以由 matplotlib 绘制,我会尝试并制作它,以便您可以绘制彩虹中 7 种以上的颜色,例如绘制跨越整个光谱的 1000 种颜色,使其看起来真的像彩虹!

Here is a modified solution of the accepted answer that uses trapezoids instead of rectangles.这是使用梯形而不是矩形的已接受答案的修改解决方案。

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):
    ax = plt.gca()
    polygon = plt.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()

polygon_rainbow_plot

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM