我正在嘗試創建一個 2D 圖,其中 4 個象限代表四個不同的階段。例如,我希望它看起來像這樣:

除了我希望中心和所有相交線中有更多的白色。
為此,我創建了一個混色器:
def combine_hex_values(d):
d_items = sorted(d.items())
tot_weight = sum(d.values())
red = int(sum([int(k[:2], 16)*v for k, v in d_items])/tot_weight)
green = int(sum([int(k[2:4], 16)*v for k, v in d_items])/tot_weight)
blue = int(sum([int(k[4:6], 16)*v for k, v in d_items])/tot_weight)
zpad = lambda x: x if len(x)==2 else '0' x
return zpad(hex(red)[2:]) zpad(hex(green)[2:]) zpad(hex(blue)[2:])
如果您更改內容的比例,它會接收具有十六進制值的顏色字典并創建混合顏色。例如,
# green, red, blue, yellow, white
cdict = {"00FF00": 0, "FF0000": 0, "0000FF": 1, "FFFF00": 0, "FFFFFF": 0}
c = "#" combine_hex_values (cdict)
keyg = "00FF00"; keyr = "FF0000"; keyb = "0000FF"; keyy = "FFFF00"; keyw = "FFFFFF";
將為藍色創建十六進制值c。但是,我不知道如何為每個格點分配顏色。這不是輪廓,因為每個點都有獨特的顏色。這是我的微不足道的嘗試:
xpoints = np.linspace (-1, 1, 10)
ypoints = np.linspace (-1, 1, 10)
R = np.sqrt(2)
color_list = []
xlat = []
ylat = []
for x in xpoints:
for y in ypoints:
for key in cdict:
cdict[key] = 0
r = np.sqrt(x*x y*y)
cdict[keyw] = 1 - r/R
if x > 0 and y > 0:
cdict[keyb] = r/R
elif x > 0 and y < 0:
cdict[keyy] = r/R
elif x < 0 and y > 0:
cdict[keyr] = r/R
elif x < 0 and y < 0:
cdict[keyg] = r/R
color_list.append ( "#" combine_hex_values (cdict) )
xlat.append (x)
ylat.append (y)
plt.scatter (xlat, ylat, c=color_list, s=90)
plt.show()
這會創建一個繪圖,但它的邊緣非常離散,并且它仍然是沒有填滿整個表面的標記。
我該如何制作上面的影像(不需要網格線)?
uj5u.com熱心網友回復:
在嘗試了一些方法之后,這些是我使用 imshow 得到的最好的結果。
如果您想將此用作另一種方法的中間步驟,請注意它result[i][j]是一個陣列[R,G,B],每個值都在 0 到 1 之間。
n = 100 # resolution along each side
lighten = .3 # factor by which to lighten corner colors
sigma = .07 # higher sigma -> more blending
# colors proceed clockwise from upper-right corner
colors = [[1,0,0], # red
[0,0,1], # blue
[1,1,0], # yellow
[0,1,0],] # green
colors = np.array(colors)
colors = lighten (1-lighten)*colors
# create 2D gradient emanating from top-left
half_range = np.linspace(0,.5,n)
grad = np.exp(-((half_range**2 half_range[:,None]**2)/sigma))
grad = grad - grad[-1,-1]
grad/=np.max(grad)
grad[grad<0] = 0
# get color contributions to each point of each corner
grads = []
layers = []
for c in colors:
layers.append(grad[:,:,None]*c[None,None,:]) # color contribution of c-colored corner
grads.append(grad)
grad = grad.T[:,::-1] # rotate gradient
layers = np.array(layers)
tot = np.array(grads).sum(axis = 0)
# combine colors at each point
p = 2
result = np.average(layers**p,axis = 0)**(1/p)/tot[:,:,None]
# saturate colors
result /= np.max(result)
plt.imshow(result)
結果影像:

另一種選擇是采用“減法”方法,然后在后期飽和。
n = 100 # resolution along each side
# lighten = 0 # factor by which to lighten corner colors
darken = 0
sigma = .05 # higher sigma -> more blending
sat = 0.4 # amount by which to "saturate" the final image (above .5 leads to data clipping)
# colors proceed clockwise from upper-right corner
colors = [[1,0,0], # red
[0,0,1], # blue
[1,1,0], # yellow
[0,1,0],] # green
colors = np.array(colors)
colors = (1-darken)*colors
colors = 1-colors
# create 2D gradient emanating from top-left
half_range = np.linspace(0,.5,n)
grad = np.exp(-((half_range**2 half_range[:,None]**2)/sigma))
grad = grad - grad[-1,-1]
grad/=np.max(grad)
grad[grad<0] = 0
# get color contributions to each point of each corner
grads = []
layers = []
for c in colors:
layers.append(grad[:,:,None]*c[None,None,:]) # color contribution of c-colored corner
grads.append(grad)
grad = grad.T[:,::-1] # rotate gradient
layers = np.array(layers)
tot = np.array(grads).sum(axis = 0)
# combine colors at each point
p = 2
result = 1-np.average(layers**p,axis = 0)**(1/p)/tot[:,:,None]
# saturate colors
result = (result - sat)/(1 - sat)
plt.imshow(result)
結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/529729.html
