[英]Getting individual colors from a color scale from colorlover in python
[英]Getting individual colors from a color map in matplotlib
如果您有一個Colormap cmap
,例如:
cmap = matplotlib.cm.get_cmap('Spectral')
如何在 0 和 1 之間獲得特定顏色,其中 0 是 map 中的第一種顏色,而 1 是 map 中的最后一種顏色?
理想情況下,我可以通過執行以下操作獲得 map 中的中間顏色:
>>> do_some_magic(cmap, 0.5) # Return an RGBA tuple
(0.1, 0.2, 0.3, 1.0)
你可以用下面的代碼來做到這一點,你的問題中的代碼實際上非常接近你所需要的,你所要做的就是調用你擁有的cmap
對象。
import matplotlib
cmap = matplotlib.cm.get_cmap('Spectral')
rgba = cmap(0.5)
print(rgba) # (0.99807766255210428, 0.99923106502084169, 0.74602077638401709, 1.0)
對於范圍 [0.0, 1.0] 之外的值,它將返回底色和底色(分別)。 默認情況下,這是該范圍內的最小和最大顏色(即 0.0 和 1.0)。 可以使用cmap.set_under()
和cmap.set_over()
更改此默認值。
對於諸如np.nan
和np.inf
之類的“特殊”數字,默認值是使用 0.0 值,這可以使用cmap.set_bad()
進行更改,類似於上面的 under 和 over。
最后,您可能需要對數據進行標准化,使其符合范圍[0.0, 1.0]
。 這可以使用matplotlib.colors.Normalize
簡單地完成,如下面的小示例所示,其中參數vmin
和vmax
描述應分別映射到 0.0 和 1.0 的數字。
import matplotlib
norm = matplotlib.colors.Normalize(vmin=10.0, vmax=20.0)
print(norm(15.0)) # 0.5
對數歸一化器 ( matplotlib.colors.LogNorm ) 也可用於具有大范圍值的數據范圍。
(感謝Joe Kington和tcaswell關於如何改進答案的建議。)
為了得到 rgba 整數值而不是浮點值,我們可以這樣做
rgba = cmap(0.5,bytes=True)
因此,為了根據 Ffisegydd 的答案簡化代碼,代碼將如下所示:
#import colormap
from matplotlib import cm
#normalize item number values to colormap
norm = matplotlib.colors.Normalize(vmin=0, vmax=1000)
#colormap possible values = viridis, jet, spectral
rgba_color = cm.jet(norm(400),bytes=True)
#400 is one of value between 0 and 1000
我正好有這個問題,但我需要連續的圖來具有高度對比的顏色。 我還使用包含參考數據的公共子圖繪制圖,因此我希望顏色序列始終可重復。
我最初嘗試簡單地隨機生成顏色,在每個繪圖之前重新播種 RNG。 這工作正常(在下面的代碼中注釋掉),但可能會產生幾乎無法區分的顏色。 我想要高度對比的顏色,最好從包含所有顏色的顏色圖中采樣。
我可以在一個圖中擁有多達 31 個數據系列,因此我將顏色圖分成了許多步驟。 然后我按順序走幾步,確保我不會很快回到給定顏色的附近。
我的數據是一個非常不規則的時間序列,所以我想查看點和線,點的顏色與線的“相反”。
鑒於上述所有內容,最容易生成帶有相關參數的字典以繪制單個系列,然后將其擴展為調用的一部分。
這是我的代碼。 也許不漂亮,但實用。
from matplotlib import cm
cmap = cm.get_cmap('gist_rainbow') #('hsv') #('nipy_spectral')
max_colors = 31 # Constant, max mumber of series in any plot. Ideally prime.
color_number = 0 # Variable, incremented for each series.
def restart_colors():
global color_number
color_number = 0
#np.random.seed(1)
def next_color():
global color_number
color_number += 1
#color = tuple(np.random.uniform(0.0, 0.5, 3))
color = cmap( ((5 * color_number) % max_colors) / max_colors )
return color
def plot_args(): # Invoked for each plot in a series as: '**(plot_args())'
mkr = next_color()
clr = (1 - mkr[0], 1 - mkr[1], 1 - mkr[2], mkr[3]) # Give line inverse of marker color
return {
"marker": "o",
"color": clr,
"mfc": mkr,
"mec": mkr,
"markersize": 0.5,
"linewidth": 1,
}
我的上下文是 JupyterLab 和 Pandas,所以這里是示例繪圖代碼:
restart_colors() # Repeatable color sequence for every plot
fig, axs = plt.subplots(figsize=(15, 8))
plt.title("%s + T-meter"%name)
# Plot reference temperatures:
axs.set_ylabel("°C", rotation=0)
for s in ["T1", "T2", "T3", "T4"]:
df_tmeter.plot(ax=axs, x="Timestamp", y=s, label="T-meter:%s" % s, **(plot_args()))
# Other series gets their own axis labels
ax2 = axs.twinx()
ax2.set_ylabel(units)
for c in df_uptime_sensors:
df_uptime[df_uptime["UUID"] == c].plot(
ax=ax2, x="Timestamp", y=units, label="%s - %s" % (units, c), **(plot_args())
)
fig.tight_layout()
plt.show()
為了建立在Ffisegydd和amaliammr的解決方案的基礎上,以下是我們為自定義顏色圖制作 CSV 表示的示例:
#! /usr/bin/env python3
import matplotlib
import numpy as np
vmin = 0.1
vmax = 1000
norm = matplotlib.colors.Normalize(np.log10(vmin), np.log10(vmax))
lognum = norm(np.log10([.5, 2., 10, 40, 150,1000]))
cdict = {
'red':
(
(0., 0, 0),
(lognum[0], 0, 0),
(lognum[1], 0, 0),
(lognum[2], 1, 1),
(lognum[3], 0.8, 0.8),
(lognum[4], .7, .7),
(lognum[5], .7, .7)
),
'green':
(
(0., .6, .6),
(lognum[0], 0.8, 0.8),
(lognum[1], 1, 1),
(lognum[2], 1, 1),
(lognum[3], 0, 0),
(lognum[4], 0, 0),
(lognum[5], 0, 0)
),
'blue':
(
(0., 0, 0),
(lognum[0], 0, 0),
(lognum[1], 0, 0),
(lognum[2], 0, 0),
(lognum[3], 0, 0),
(lognum[4], 0, 0),
(lognum[5], 1, 1)
)
}
mycmap = matplotlib.colors.LinearSegmentedColormap('my_colormap', cdict, 256)
norm = matplotlib.colors.LogNorm(vmin, vmax)
colors = {}
count = 0
step_size = 0.001
for value in np.arange(vmin, vmax+step_size, step_size):
count += 1
print("%d/%d %f%%" % (count, vmax*(1./step_size), 100.*count/(vmax*(1./step_size))))
rgba = mycmap(norm(value), bytes=True)
color = (rgba[0], rgba[1], rgba[2])
if color not in colors.values():
colors[value] = color
print ("value, red, green, blue")
for value in sorted(colors.keys()):
rgb = colors[value]
print("%s, %s, %s, %s" % (value, rgb[0], rgb[1], rgb[2]))
我曾經遇到過類似的情況,我需要“n”不。 顏色圖中的顏色,以便我可以將每種顏色分配給我的數據。 我在一個名為“ mycolorpy ”的包中為此編譯了一個代碼。 您可以使用以下命令 pip 安裝它:
pip install mycolorpy
然后你可以這樣做:
from mycolorpy import colorlist as mcp
import numpy as np
示例:從“winter”營創建一個包含 5 個十六進制字符串的列表
color1=mcp.gen_color(cmap="winter",n=5)
print(color1)
輸出:
['#0000ff', '#0040df', '#0080bf', '#00c09f', '#00ff80']
另一個從 Camp bwr 生成 16 種顏色列表的示例:
color2=mcp.gen_color(cmap="bwr",n=16)
print(color2)
輸出:
['#0000ff', '#2222ff', '#4444ff', '#6666ff', '#8888ff', '#aaaaff', '#ccccff', '#eeeeff', '#ffeeee', '#ffcccc', '#ffaaaa', '#ff8888', '#ff6666', '#ff4444', '#ff2222', '#ff0000']
有一個帶有使用示例的python 筆記本,可以更好地可視化這一點。
假設您想從標准化為給定數據的 cmap 生成顏色列表。 你可以使用:
a=random.randint(1000, size=(200))
a=np.array(a)
color1=mcp.gen_color_normalized(cmap="seismic",data_arr=a)
plt.scatter(a,a,c=color1)
您還可以使用以下方法反轉顏色:
color1=mcp.gen_color_normalized(cmap="seismic",data_arr=a,reverse=True)
plt.scatter(a,a,c=color1)
顏色圖帶有自己的歸一化方法,因此如果您已經繪制了繪圖,則可以訪問特定值的顏色。
import matplotlib.pyplot as plt
import numpy as np
cmap = plt.cm.viridis
cm = plt.pcolormesh(np.random.randn(10, 10), cmap=cmap)
print(cmap(cm.norm(2.2)))
為了快速而骯臟,您可以直接使用 map。 或者你可以按照@amaliammr 所說的去做。
data_size = 23 # range 0..23
colors = plt.cm.turbo
color_normal = colours.N/data_size
for i in range(data_size):
col = colours.colors[int(i*color_normal)]
如果您有 Colormap cmap
,例如:
cmap = matplotlib.cm.get_cmap('Spectral')
如何從 0 到 1 之間獲取特定顏色,其中 0 是地圖中的第一種顏色,而 1 是地圖中的最后一種顏色?
理想情況下,我可以通過執行以下操作獲得地圖中的中間顏色:
>>> do_some_magic(cmap, 0.5) # Return an RGBA tuple
(0.1, 0.2, 0.3, 1.0)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.