python - 使用 matplotlib/pyplot 混合线条颜色绘制曲线

标签 python image matplotlib plot colors

我想以一种颜色开始曲线,然后逐渐混合到另一种颜色直到结束。我的 MCVE 中的以下函数可以工作,但是肯定有更好的方法我还没有发现?!

import numpy as np
import matplotlib.pyplot as plt

def colorlist(color1, color2, num):
    """Generate list of num colors blending from color1 to color2"""
    result = [np.array(color1), np.array(color2)]
    while len(result) < num:
        temp = [result[0]]
        for i in range(len(result)-1):
            temp.append(np.sqrt((result[i]**2+result[i+1]**2)/2))
            temp.append(result[i+1])
        result = temp
    indices = np.linspace(0, len(result)-1, num).round().astype(int)
    return [result[i] for i in indices]

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
colors = colorlist((1, 0, 0), (0, 0, 1), len(x))

for i in range(len(x)-1):
    xi = x[i:i+1+1]
    yi = y[i:i+1+1]
    ci = colors[i]
    plt.plot(xi, yi, color=ci, linestyle='solid', linewidth='10')

plt.show()

1

最佳答案

不确定“更好的方法”指的是什么。代码较少且绘制速度更快的解决方案是将 LineCollection 与颜色图一起使用。

颜色图可以由两种颜色定义,并且之间的任何颜色都会自动插值。

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", [(1, 0, 0), (0, 0, 1)])

LineCollection 可用于一次绘制多条线。作为 ScalarMappable,它可以使用颜色图根据某个数组对每条线进行不同的着色 - 在这种情况下,可以仅使用 x 值来实现此目的。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import LinearSegmentedColormap

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

cmap = LinearSegmentedColormap.from_list("", [(1, 0, 0), (0, 0, 1)])

points = np.array([x, y]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-1],points[1:]], axis=1)

lc = LineCollection(segments, cmap=cmap, linewidth=10)
lc.set_array(x)
plt.gca().add_collection(lc)
plt.gca().autoscale()
plt.show()

enter image description here

如图所示,该解决方案的缺点是各个线路连接不良。

因此,为了避免这种情况,可以使用以下方法将这些点重叠绘制

segments = np.concatenate([points[:-2],points[1:-1], points[2:]], axis=1)

enter image description here

<小时/> 在上面的颜色中,颜色是在两个给定颜色之间线性插值的。因此,该图看起来与使用某种自定义插值的问题中的图不同。

enter image description here

要获得与问题中相同的颜色,您可以使用相同的函数来创建 LineCollection 的颜色图中使用的颜色。如果目的是简化此函数,您可以直接将值计算为 channel 中色差的平方根。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import LinearSegmentedColormap

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

def colorlist2(c1, c2, num):
    l = np.linspace(0,1,num)
    a = np.abs(np.array(c1)-np.array(c2))
    m = np.min([c1,c2], axis=0)
    s  = np.sign(np.array(c2)-np.array(c1)).astype(int)
    s[s==0] =1
    r = np.sqrt(np.c_[(l*a[0]+m[0])[::s[0]],(l*a[1]+m[1])[::s[1]],(l*a[2]+m[2])[::s[2]]])
    return r

cmap = LinearSegmentedColormap.from_list("", colorlist2((1, 0, 0), (0, 0, 1),100))

points = np.array([x, y]).T.reshape(-1,1,2)
segments = np.concatenate([points[:-2],points[1:-1], points[2:]], axis=1)

lc = LineCollection(segments, cmap=cmap, linewidth=10)
lc.set_array(x)
plt.gca().add_collection(lc)
plt.gca().autoscale()
plt.show()

enter image description here

关于python - 使用 matplotlib/pyplot 混合线条颜色绘制曲线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47851492/

相关文章:

android - 免费变换 Android 图像

python - 如何将彩色贴图图像反转为标量值?

python - 在 python (matplotlib) 中优雅地停止(而不是暂停)动画情节

python - Windrose axespad 的意思

python - 如何在 Django 1.8 中连接表

python - 在 Azure 功能中部署后 wkhtmltopdf 无法正常工作

python - 如何在python中的字典列表中查找项目的累计总和

python - abaqus脚本: TypeError: cannot concatenate 'str' and 'Set' objects

php - 用 WooCommerce 中特定类别的占位符替换产品图片

image - Firebug 显示图像下载两次