如何用Python制作颜色网格?

问题描述 投票:0回答:1

我正在尝试创建一个表示颜色混合比例的值网格。我在图中提供了一个示例。我面临的挑战是,对于高值,对角线下方和上方的颜色应该不同。在示例中,我使用条件格式为单元格着色,但我需要一种方法来实现此目的而不显示数字。我相信使用 Python 可以做到这一点。我遇到过一些示例(例如Python - 根据值绘制彩色网格中的示例),但没有一个具体解决由对角线分隔不同颜色的问题。

The image was created in google sheets to better explain the problem. You see a mixture of red and green below the diagonal and red and blue above the diagonal

我相信代码一定是这样的,但是考虑到另一个对角线。

import matplotlib.pyplot as plt
import numpy as np

# Define grid size
n = 20

# Create a grid with zeros
grid = np.zeros((n, n, 3))

# Fill lower triangle with mixtures of red and green
for i in range(n):
    for j in range(i):
        grid[i, j] = [1, np.random.rand(), 0]

# Fill upper triangle with mixtures of red and blue
for i in range(n):
    for j in range(i + 1, n):
        grid[i, j] = [1, 0, np.random.rand()]

# Display the grid
plt.imshow(grid)
plt.axis('off')  # Turn off axis labels
plt.show()
python colors grid
1个回答
0
投票

我找到了缺失的概念。我想做的是创建一个二元色彩图。完整的答案可以在此链接中找到:https://waterprogramming.wordpress.com/2022/09/08/bivariate-choropleth-maps/

下面,我分享了我修改后的代码(我只需要清理一些细节)。积分归上面链接的所有者所有。

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.collections import PatchCollection
from matplotlib.colors import rgb2hex
from generativepy.color import Color
from PIL import ImageColor

alpha=0.85

### percentile bounds defining upper boundaries of color classes
percentile_bounds = [25, 50, 75, 100]

### function to convert hex color to rgb to Color object (generativepy package)
def hex_to_Color(hexcode):
    rgb = ImageColor.getcolor(hexcode, 'RGB')
    rgb = [v/256 for v in rgb]
    rgb = Color(*rgb)
    return rgb

### get corner colors from https://www.joshuastevens.net/cartography/make-a-bivariate-choropleth-map/
c00 = hex_to_Color('#e8e8e8')
c10 = hex_to_Color('#be64ac')
c01 = hex_to_Color('#5ac8c8')
c11 = hex_to_Color('#3b4994')

### now create square grid of colors, using color interpolation from generativepy package
num_grps = len(percentile_bounds)
c00_to_c10 = []
c01_to_c11 = []
colorlist = []
for i in range(num_grps):
    c00_to_c10.append(c00.lerp(c10, 1/(num_grps-1) * i))
    c01_to_c11.append(c01.lerp(c11, 1/(num_grps-1) * i))
for i in range(num_grps):
    for j in range(num_grps):
        colorlist.append(c00_to_c10[i].lerp(c01_to_c11[i], 1/(num_grps-1) * j))
 
### convert back to hex color
colorlist = [rgb2hex([c.r, c.g, c.b]) for c in colorlist]

### function to get bivariate color given two percentiles
def get_bivariate_choropleth_color(p1, p2):
    if p1>=0 and p2>=0:
        count = 0
        stop = False
        for percentile_bound_p1 in percentile_bounds:
            for percentile_bound_p2 in percentile_bounds:
                if (not stop) and (p1 <= percentile_bound_p1):
                    if (not stop) and (p2 <= percentile_bound_p2):
                        color = colorlist[count]
                        stop = True
                count += 1
    else:
        color = [0.8,0.8,0.8,1]
    return color

### plot map based on bivariate choropleth
fig, ax = plt.subplots(1,1, figsize=(8,10))

ax.set_aspect('equal', adjustable='box')
count = 0
xticks = [0]
yticks = [0]
for i,percentile_bound_p1 in enumerate(percentile_bounds):
    for j,percentile_bound_p2 in enumerate(percentile_bounds):
        percentileboxes = [Rectangle((i,j), 1, 1)]
        pc = PatchCollection(percentileboxes, facecolor=colorlist[count], alpha=alpha)
        count += 1
        ax.add_collection(pc)
        if i == 0:
            yticks.append(percentile_bound_p2)
    xticks.append(percentile_bound_p1)

_=ax.set_xlim([0,len(percentile_bounds)])
_=ax.set_ylim([0,len(percentile_bounds)])
_=ax.set_xticks(list(range(len(percentile_bounds)+1)), xticks)
_=ax.set_xlabel('Pollution burden percentile')
_=ax.set_yticks(list(range(len(percentile_bounds)+1)), yticks)
_=ax.set_ylabel('Population characteristics percentile')

plt.show()

# to save the figure directly
# plt.savefig(f'/home/ed2020/Desktop/Arquivos/Qgis/exemplo/bivariate.jpg', dpi=dpi, bbox_inches='tight')
© www.soinside.com 2019 - 2024. All rights reserved.