2024-05-16 12:50:09 发布
网友
我有一个2d向量(x,y),我需要找到一个2d颜色贴图,将这些坐标映射到平滑的颜色贴图。颜色代码将仅取决于(x,y)值。比如说,
(x,y)
换言之:
green red white green blue
我在{}中找不到符合我需要的东西。我曾想过将坐标转换为幅值和相位,但问题仍然是一样的。我还考虑在向量(x,y)中添加一个虚拟维度,使其成为三维维度,然后对生成的三维向量进行规格化。然后,将其馈送到matplotlib图中的cmap参数。但是,这会产生不平滑的颜色。有线索吗
matplotlib
cmap
颜色贴图的示例:
我会使用像hsl或hsv这样的颜色空间,固定亮度值(l或v),并使用x作为h,y作为s来表示所有颜色。您将需要规范化x和y的值,使其与颜色空间组件兼容
因此,为了重申这个问题以确保我正确理解它:您希望有两个不同的colormap通道,而不是一个
在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到颜色功能执行任何操作,但这里有两个建议:
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)
看起来您所需的颜色贴图需要更多的规则来将XY区域转换为所需的颜色,并使用渐变/混合函数从一个区域过渡到另一个区域,类似于4中所示的梯形混合。在你想要的地图上面
x<=0
x >0 & y < 0
x > 0 & y >= 0
white
实现这一点的一种方法可能是在图形程序(如Gimp或Inkscape)中创建具有所需颜色的点网格,调整关键坐标和指定的颜色三元组(RGB、HSL或HSV),直到您对外观满意,然后使用scipy.interpolate.griddata5为XY数据插值3个颜色通道中的每一个,例如:
scipy.interpolate.griddata
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)
注意:只要我编写自己的颜色空间转换函数,我就可以直接从HSL转换为RGB3,但也许有一位评论员可以解释为什么matplotlib.colors有hsv_to_rgb而没有hsl_to_rgb(运行matplotlib v.3.3.2)
hsv_to_rgb
hsl_to_rgb
我会使用像hsl或hsv这样的颜色空间,固定亮度值(l或v),并使用x作为h,y作为s来表示所有颜色。您将需要规范化x和y的值,使其与颜色空间组件兼容
因此,为了重申这个问题以确保我正确理解它:您希望有两个不同的colormap通道,而不是一个
在matplotlib中,我看不到直接的方法,有两个选项:
对于“hack-y”多重打印解决方案:
产生
您可以对自定义2D到颜色功能执行任何操作,但这里有两个建议:
产生
看起来您所需的颜色贴图需要更多的规则来将XY区域转换为所需的颜色,并使用渐变/混合函数从一个区域过渡到另一个区域,类似于4中所示的梯形混合。在你想要的地图上面
x<=0
x >0 & y < 0
x > 0 & y >= 0
,并且white
是{实现这一点的一种方法可能是在图形程序(如Gimp或Inkscape)中创建具有所需颜色的点网格,调整关键坐标和指定的颜色三元组(RGB、HSL或HSV),直到您对外观满意,然后使用
scipy.interpolate.griddata
5为XY数据插值3个颜色通道中的每一个,例如:产生
注意:只要我编写自己的颜色空间转换函数,我就可以直接从HSL转换为RGB3,但也许有一位评论员可以解释为什么matplotlib.colors有
hsv_to_rgb
而没有hsl_to_rgb
(运行matplotlib v.3.3.2)相关问题 更多 >
编程相关推荐