[英]2D colormap in Python
我有一个 2d 向量(x,y)
,我需要找到一个 2D 颜色图,将这些坐标映射到一个平滑的颜色图。 颜色代码将仅取决于(x,y)
值。 例如,
换句话说:
green red
white
green blue
我在matplotlib
中没有找到任何符合我需要的东西。 我考虑过将坐标转换为幅度和相位,但问题仍然相同。 我还考虑为向量(x,y)
添加一个虚拟维度,使其成为 3d 维度,然后对生成的 3D 向量进行归一化。 然后,将其提供给matplotlib
图中的cmap
参数。 但是,这会产生不平滑的 colors。 有什么线索吗?
颜色 map 的样本:
我会使用像 hsl 或 hsv 这样的颜色空间并固定亮度值(l 或 v),并使用 x 作为 h 和 y 作为 s 来表示所有 colors。 您将需要标准化 x 和 y 的值,以使它们与颜色空间组件兼容。
所以要重申这个问题以确保我正确理解它:您想要两个不同的颜色图通道,而不是一个?
我在 matplotlib 中没有看到直接的方法,有两种选择:
对于“hack-y”多重绘图解决方案:
import numpy as np
from matplotlib.colors import hsv_to_rgb, rgb_to_hsv
import matplotlib.pyplot as plt
xydata = np.array([(x,y) for x in np.arange(-1.,1.1,0.1) for y in np.arange(-1.,1.1,0.1)], dtype=float)
x_colorfunc = lambda xy: xy.T[0].max() - np.abs(xy.T[0])
y_colorfunc = lambda xy: np.abs(xy.T[1])
y_colormap_coord = y_colorfunc(xydata)
x_colormap_coord = x_colorfunc(xydata)
x_colormap = "plasma"
y_colormap = "Greys"
plt.figure("2d_colormap_hack")
plt.scatter(xydata.T[0], xydata.T[1], c=x_colormap_coord, cmap= x_colormap, alpha=1.0)
plt.scatter(xydata.T[0], xydata.T[1], c=y_colormap_coord, cmap= y_colormap, alpha=0.6)
哪个生产
您可以对自定义 2D 转彩色 function 做任何您想做的事情,但这里有两个建议:
def xy_color_func(xy):
# using np.divide handles `RuntimeWarning: divide by zero encountered in true_divide`
xy_ratio = np.divide(xy.T[1], xy.T[0], out=np.ones_like(xy.T[0]), where=(xy.T[0]!=0) )
xy_angle_frac = (4/np.pi)*np.abs(np.arctan(xy_ratio))
xy_mag = np.linalg.norm(xy, axis=-1)
hsl_hue = 1 - 1./6*xy_angle_frac # hue goes from red to blue
hsl_sat = 1 - xy_mag/xy_mag.max() # 0 is full color saturation, 1 is equal RGB values
hsl_luminance = 0.75 - 0.25*(xy_mag/xy_mag.max()) # brighter at the "target" point of (0, 0)
hsv = hsl_to_hsv(hsl_hue, hsl_sat, hsl_luminance)
rgb = hsv_to_rgb(hsv)
return rgb
def hsl_to_hsv(hsl_hue, hsl_sat, hsl_luminance):
hsv_hue = hsl_hue
hsv_v = hsl_luminance + hsl_sat*np.minimum(hsl_luminance, 1-hsl_luminance)
hsv_sat = 2*(1-np.divide(hsl_luminance, hsv_v, out=np.ones_like(hsv_v), where=(hsv_v!=0) ))
hsv = np.vstack((hsv_hue, hsv_sat, hsv_v)).T
return hsv
xy_colors = xy_color_func(xydata)
plt.figure("2d_colormap_func")
plt.scatter(xydata.T[0], xydata.T[1], c=xy_colors)
哪个生产
看起来您想要的颜色 map 需要更多规则才能将 XY 区域转换为所需的 colors,以及渐变/混合 ZC1C425268E68385D1AB5074C17A914Zoid 从一个区域到另一个区域的过渡,类似于从一个区域到另一个区域的44F14Z过渡。 在您想要的 map 上面,
x<=0
,x >0 & y < 0
,x > 0 & y >= 0
,并且white
是1-magnitude(x,y)
, 实现此目的的一种方法可能是在图形程序(如 Gimp 或 Inkscape)中制作具有所需颜色的点网格,调整关键坐标和指定颜色三元组(RGB、HSL 或 HSV)直到您满意外观,然后使用scipy.interpolate.griddata
5为您的 XY 数据插入 3 个颜色通道中的每一个,如下所示:
key_xy_points = np.array([[0,0],[1,0],[1,1],[1,-1],[-1,1], [-1,-1]],dtype=float)
key_xy_RGBs = np.array([[1,1,1], [1,1,1], [0,0,1], [1,0,0], [0,1,0], [0,1,0]],dtype=float)
from scipy.interpolate import griddata
reds = griddata(key_xy_points, key_xy_RGBs.T[0], xydata)
greens = griddata(key_xy_points, key_xy_RGBs.T[1], xydata)
blues = griddata(key_xy_points, key_xy_RGBs.T[2], xydata)
xy_colors_griddata = np.vstack((reds, greens, blues)).T
plt.figure("2d_colormap_griddata")
plt.scatter(xydata.T[0], xydata.T[1], c=xy_colors_griddata)
哪个生产
Note: As long as I was writing my own colorspace conversion function, I could have converted directly from HSL to RGB 3 , but perhaps one of the commenters can explain why matplotlib.colors has hsv_to_rgb
but not an hsl_to_rgb
(running matplotlib v.3.3. 2)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.