matplotlib中的渐变填充和颜色过渡

时间:2018-05-26 09:42:26

标签: python matplotlib

Image example

在示例图中,我有两个无色区域。我想在两个区域过渡时绘制平滑的颜色过渡。例如,我想在无色区域的最左边部分开始用黄色,然后慢慢过渡到橙色,最右边的橙色强度最强。

有什么办法可以做到吗?我不确定是否可以使用fill_between来完成。

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
matplotlib.rcParams['font.sans-serif'] = "Arial"
matplotlib.rcParams['font.family'] = "sans-serif"

#points for the three lines
x_1=[0.00,1.00,2.00,3.00,4.00,5.00,6.00,6.50]
y_1=[3.00,2.80,2.40,2.20,1.80,1.00,0.20,0.00]

x_2 = [0.00,1.00,2.00,2.80]
y_2 = [7.00,8.00,9.00,10.00]

x_3=[2.80,2.80,3.00,4.00]
y_3=[10.00,6.00,4.00,1.80]

#create comparison arrays for fill_between
y_1_compare=[]
for item in x_1:
    y_1_compare.append(0)

y_2_compare=[]
for item in x_2:
    y_2_compare.append(10)

f=plt.figure(figsize=(5,5))
ax=plt.gca()
plt.plot(x_1,y_1,'o',linestyle='-', color='k',linewidth=0.7)
plt.plot(x_2,y_2,'s',linestyle='-',color='k',linewidth=0.7)
plt.plot(x_3,y_3,'^',linestyle='--',color='k',linewidth=0.7)
ax.set_xlim(0,8)
ax.set_ylim(0,10)
ax.fill_between(x_1, y_1, y_1_compare, where=y_1 >= y_1_compare, facecolor='tab:cyan', interpolate=True,alpha=0.6)
ax.fill_between(x_2, y_2, y_2_compare, where=y_2 <= y_2_compare, facecolor='green', interpolate=True,alpha=0.4)
ax.tick_params(labelsize=15)
plt.show()

1 个答案:

答案 0 :(得分:0)

通常的方法是利用imshow执行此任务。您当然可以创建一个区域大小的补丁,并用渐变颜色填充它。或者您只是首先绘制渐变,然后绘制所有元素:

import matplotlib
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
matplotlib.rcParams['font.sans-serif'] = "Arial"
matplotlib.rcParams['font.family'] = "sans-serif"

#points for the three lines
x_1=[0.00,1.00,2.00,3.00,4.00,5.00,6.00,6.50]
y_1=[3.00,2.80,2.40,2.20,1.80,1.00,0.20,0.00]

x_2 = [0.00,1.00,2.00,2.80]
y_2 = [7.00,8.00,9.00,10.00]

x_3=[2.80,2.80,3.00,4.00]
y_3=[10.00,6.00,4.00,1.80]

#create comparison arrays for fill_between
y_1_compare=[]
for item in x_1:
    y_1_compare.append(0)

y_2_compare=[]
for item in x_2:
    y_2_compare.append(10)

f=plt.figure(figsize=(5,5))
ax=plt.gca()
#define size of the graph
xl = 0
xh = 8
yl = 0
yh = 10
#array for gradient creation
arr = [[0, 1], [0, 1]]

#plot a gradient picture first in the desired size, which will also autoscale the graph
#set interpolation to "nearest" to see the underlying grid structure
im1 = plt.imshow(arr,  cmap = cm.Oranges, extent = [xl, xh, yl, yh], interpolation = "bicubic", alpha = .6, aspect = "auto")

plt.plot(x_1,y_1,'o',linestyle='-', color='k',linewidth=0.7)
plt.plot(x_2,y_2,'s',linestyle='-',color='k',linewidth=0.7)
plt.plot(x_3,y_3,'^',linestyle='--',color='k',linewidth=0.7)

#fill the areas with white, so we won't see the underlying picture, when we plot a colour with a reduced alpha
ax.fill_between(x_1, y_1, y_1_compare, where=y_1 >= y_1_compare, facecolor='white', interpolate=True,alpha=1)
ax.fill_between(x_2, y_2, y_2_compare, where=y_2 <= y_2_compare, facecolor='white', interpolate=True,alpha=1)
#now plot again color with reduced alpha
ax.fill_between(x_1, y_1, y_1_compare, where=y_1 >= y_1_compare, facecolor='tab:cyan', interpolate=True,alpha=.4)
ax.fill_between(x_2, y_2, y_2_compare, where=y_2 <= y_2_compare, facecolor='green', interpolate=True,alpha=.6)
ax.tick_params(labelsize=15)
plt.show()

输出:

enter image description here

有很多predefined colormaps,会让你忙碌一段时间。列表[[0, 1], [0, 1]]当然可以是任何类型的数组,而不仅仅是粗略的2 x 2网格。试试例如:

sp = np.linspace(0, 1, 10)
spy = np.tile(sp, 3)
arr = sp[:, None] * spy[None, :]