如何获取颜色图的一部分
How to get part of a colormap
我正在 class 中绘制来自数据框 "self.data" 的一些曲线。 dataframe的每一列都是一条曲线,列名写在行尾。
我制作这个程序是为了这样做:
cmap = plt.cm.get_cmap('brg', len(self.data.columns)+1)
for i in range(len(self.data.columns)): #plot curves and add legend
self.courbe.plot(self.data[self.data.columns[i]],c=cmap(i))
angle=20
self.courbe.annotate(self.data.columns[i],
xy= (max(self.data.index),self.data.at[max(self.data.index),self.data.columns[i]]),
textcoords='offset points',
xytext=(2, 0),
va='bottom',
rotation=angle,c=cmap(i))
所以我使用了 "brg" 颜色图,但我只想使用该颜色图的一部分(例如删除浅绿色部分)。
我在 Whosebug 上尝试了一些建议的解决方案,例如 how to extract a subset of a colormap as a new colormap in matplotlib?,但所有曲线都是相同的颜色。有人知道另一种方法吗?
谢谢,祝你有美好的一天:)
A norm
用于将数字范围映射到颜色图所需的范围 0..1。我们可以创建一个特殊的规范来获得想要的效果。
范数取决于最低索引 vmin 和最高索引 vmax。 vmin
将映射到 0,vmax 将映射到 1。
选择上下颜色(均在 0 和 1 之间),例如 upper=0.9 在 bgr 中的浅绿色处停止。降低=0 使所有颜色达到深蓝色。
公式找到 vmin 和 vmax,它们将索引 i=0
映射到 lower_color 并将索引 i=num_colors-1
映射到 upper_color。该公式遵循映射的唯一线性方程:
0
到 lower_color
num_colors - 1
到 upper_color
vmin
到 0
vmax
到 1
您发现值 i=0..num_colors-1
的颜色索引为 norm(i)
,对应的颜色为 cmap(norm(i))
。
import matplotlib.pyplot as plt
import matplotlib as mpl
cmap = plt.cm.get_cmap('brg')
# between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
upper_color = 0.8
lower_color = 0.3
num_colors = 20 # len(self.data.columns)
factor = (num_colors - 1)/(upper_color - lower_color)
norm = mpl.colors.Normalize(vmin=-lower_color*factor, vmax=(1 - lower_color)*factor)
for i in range(num_colors):
plt.plot([0, 1], [0, i], c=cmap(norm(i)))
plt.show()
使用 brg
地图并在 0.3 和 0.8 之间选择颜色的示例,只是为了展示它是如何工作的。作为参考,有一个应用了相同限制的颜色条。 brg
.
的完整颜色条
颜色条生成如下:
c_map_ax = plt.gcf().add_axes([0.84, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax, cmap=cmap, orientation='vertical')
c_map_ax.axes.set_ylim(lower_color, upper_color)
c_map_ax2 = plt.gcf().add_axes([0.92, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax2, cmap=cmap, orientation='vertical')
plt.subplots_adjust(right=0.8)
其他答案使用的因素可能有点不直观;因此这里是一样的,只是没有任何规范或因素。您仍然需要在 0 和 1 之间选择一个较低和较高的值,并从颜色图中获取该范围内的颜色。然后遍历它们:
import matplotlib.pyplot as plt
import numpy as np
cmap = plt.cm.get_cmap('brg')
# between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
upper_color = 0.8
lower_color = 0.3
num_colors = 20 # len(self.data.columns)
colors = cmap(np.linspace(lower_color, upper_color, num_colors))
for i, color in enumerate(colors):
plt.plot([0, 1], [0, i], color=color)
plt.show()
我正在 class 中绘制来自数据框 "self.data" 的一些曲线。 dataframe的每一列都是一条曲线,列名写在行尾。
我制作这个程序是为了这样做:
cmap = plt.cm.get_cmap('brg', len(self.data.columns)+1)
for i in range(len(self.data.columns)): #plot curves and add legend
self.courbe.plot(self.data[self.data.columns[i]],c=cmap(i))
angle=20
self.courbe.annotate(self.data.columns[i],
xy= (max(self.data.index),self.data.at[max(self.data.index),self.data.columns[i]]),
textcoords='offset points',
xytext=(2, 0),
va='bottom',
rotation=angle,c=cmap(i))
所以我使用了 "brg" 颜色图,但我只想使用该颜色图的一部分(例如删除浅绿色部分)。
我在 Whosebug 上尝试了一些建议的解决方案,例如 how to extract a subset of a colormap as a new colormap in matplotlib?,但所有曲线都是相同的颜色。有人知道另一种方法吗?
谢谢,祝你有美好的一天:)
A norm
用于将数字范围映射到颜色图所需的范围 0..1。我们可以创建一个特殊的规范来获得想要的效果。
范数取决于最低索引 vmin 和最高索引 vmax。 vmin
将映射到 0,vmax 将映射到 1。
选择上下颜色(均在 0 和 1 之间),例如 upper=0.9 在 bgr 中的浅绿色处停止。降低=0 使所有颜色达到深蓝色。
公式找到 vmin 和 vmax,它们将索引 i=0
映射到 lower_color 并将索引 i=num_colors-1
映射到 upper_color。该公式遵循映射的唯一线性方程:
0
到lower_color
num_colors - 1
到upper_color
vmin
到0
vmax
到1
您发现值 i=0..num_colors-1
的颜色索引为 norm(i)
,对应的颜色为 cmap(norm(i))
。
import matplotlib.pyplot as plt
import matplotlib as mpl
cmap = plt.cm.get_cmap('brg')
# between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
upper_color = 0.8
lower_color = 0.3
num_colors = 20 # len(self.data.columns)
factor = (num_colors - 1)/(upper_color - lower_color)
norm = mpl.colors.Normalize(vmin=-lower_color*factor, vmax=(1 - lower_color)*factor)
for i in range(num_colors):
plt.plot([0, 1], [0, i], c=cmap(norm(i)))
plt.show()
使用 brg
地图并在 0.3 和 0.8 之间选择颜色的示例,只是为了展示它是如何工作的。作为参考,有一个应用了相同限制的颜色条。 brg
.
颜色条生成如下:
c_map_ax = plt.gcf().add_axes([0.84, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax, cmap=cmap, orientation='vertical')
c_map_ax.axes.set_ylim(lower_color, upper_color)
c_map_ax2 = plt.gcf().add_axes([0.92, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax2, cmap=cmap, orientation='vertical')
plt.subplots_adjust(right=0.8)
其他答案使用的因素可能有点不直观;因此这里是一样的,只是没有任何规范或因素。您仍然需要在 0 和 1 之间选择一个较低和较高的值,并从颜色图中获取该范围内的颜色。然后遍历它们:
import matplotlib.pyplot as plt
import numpy as np
cmap = plt.cm.get_cmap('brg')
# between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
upper_color = 0.8
lower_color = 0.3
num_colors = 20 # len(self.data.columns)
colors = cmap(np.linspace(lower_color, upper_color, num_colors))
for i, color in enumerate(colors):
plt.plot([0, 1], [0, i], color=color)
plt.show()