使用matplotlib根据亮度绘制颜色。

huangapple go评论68阅读模式
英文:

Plotting colors by brightness with matplotlib

问题

我想从这个事实开始,这不是一个关于如何确定颜色亮度的问题!

所以,我的问题是,我正在寻找一种方法来按颜色的亮度排列一组颜色。我有一个函数,它使用所有在这里提到的方法以及更多方法来计算亮度__这里__。这是一篇很棒的文章,几乎完全符合我所需的,但有几件事情我不太确定,所以将它作为示例会帮助我很多,可以更好地解释我试图实现的目标。

我想使用__matplotlib.pyplot__构建整个图表,而不是使用bokeh。Bokeh做得很好,但我需要与项目中的其他元素保持一致,所以我需要使用matplotlib重新构建它。我尝试了一些方法,但无法得到我想要的结果。

此外,如果我能够不按照文章中的方式创建图表,而是__垂直排列__它,类似于__这里的答案中的答案,具体来说,是___Petr Hurtak___和___Kal___的答案,只是在一个__正方形__内进行,而不是像他们所做的那样使用一个__细长的垂直矩形

从提到的文章中获取的有用图像:
使用matplotlib根据亮度绘制颜色。
使用matplotlib根据亮度绘制颜色。

英文:

I want to start with the fact that this IS NOT a question on how to determine the brightness of a color!

So, my problem is that I'm searching for a way to arrange a collection of colors by their brightness. I have a function that calculates the brightness with all of the methods mentioned here and more. This is a great article that does almost exactly what I need but I'm not sure about a couple of things, so having it as an example would help me a lot in explaining what I'm trying to achieve.

I want to construct the whole plot with all colors using matplotlib.pyplot instead of using bokeh. Bokeh does a great job but I need to be consistent with other things in my project so I need to reconstruct it with matplotlib. I tried a few methods but couldn't achieve the results I was looking for.

Also, it would be great if instead of creating the plot the way it's created in the article, I could create it vertically, similar to the ones from the answers here, more specifically, the answers by Petr Hurtak and Kal, only do it in a square instead of using an elongated vertical rectangle like they did.

Helpful images taken from the mentioned articles:
使用matplotlib根据亮度绘制颜色。
使用matplotlib根据亮度绘制颜色。

答案1

得分: 2

Colour可以通过使用更好的感知均匀颜色空间(例如JzAzBz,Oklab,ICtCp)来实现此目的:

import colour
import numpy as np

RGB = np.random.random((256, 256, 3))
colour.plotting.plot_image(RGB);

RGB_f = np.reshape(RGB, (-1, 3))
L = colour.convert(RGB_f, "RGB", "Oklab")[..., 0]
colour.plotting.plot_image(
    colour.utilities.orient(RGB_f[L.argsort()].reshape(RGB.shape), "Flop"));

使用matplotlib根据亮度绘制颜色。
使用matplotlib根据亮度绘制颜色。

您还可以按照以下方式将它们显示为网格,尽管在较高分辨率下速度较慢:

RGB = np.random.random((64, 64, 3))
RGB_f = np.reshape(RGB, (-1, 3))
L = colour.convert(RGB_f, "RGB", "Oklab")[..., 0]
colour.plotting.plot_multi_colour_swatches(
    RGB_f[L.argsort()], columns=RGB.shape[0], spacing=0.5, background_colour="k");

使用matplotlib根据亮度绘制颜色。

如果您希望在浏览器中直接尝试,请使用Google Colab笔记本:链接

英文:

Colour would allow to do that by also using a better perceptually uniform colourspace, e.g. JzAzBz, Oklab, ICtCp:

import colour
import numpy as np

RGB = np.random.random((256, 256, 3))
colour.plotting.plot_image(RGB);

RGB_f = np.reshape(RGB, (-1, 3))
L = colour.convert(RGB_f, "RGB", "Oklab")[..., 0]
colour.plotting.plot_image(
    colour.utilities.orient(RGB_f[L.argsort()].reshape(RGB.shape), "Flop"));

使用matplotlib根据亮度绘制颜色。
使用matplotlib根据亮度绘制颜色。

You could also display them as a grid as follows, although this is much slower at higher resolution:

RGB = np.random.random((64, 64, 3))
RGB_f = np.reshape(RGB, (-1, 3))
L = colour.convert(RGB_f, "RGB", "Oklab")[..., 0]
colour.plotting.plot_multi_colour_swatches(
    RGB_f[L.argsort()], columns=RGB.shape[0], spacing=0.5, background_colour="k");

使用matplotlib根据亮度绘制颜色。

Here is a Google Colab notebook if you want to try in the browser directly: https://colab.research.google.com/drive/1SD-ZU1clsHgHFyC0gpIP2fK9xBvYX-oS?usp=sharing

答案2

得分: 0

以下是您提供的内容的翻译:

  1. 生成随机颜色。首先,选择所需的颜色数量,然后获取该数量的四舍五入的平方根的幂。这样做是为了获得一个具有整数平方根的数字,以便后面得到一个完美的宽度 x 高度的网格。

    desired_no_colors = 5000
    no_colors = round(np.sqrt(desired_no_colors))**2
    # 生成颜色
    color_list = np.array([(np.random.choice(range(256), size=3)) for _ in np.arange(no_colors)])
    color_list = color_list / 255 # 将值转换为0-1范围
    
  2. 使用该列表创建一个 pandas 数据框
    color_df = pd.DataFrame({'颜色': list(color_list)})

  3. 定义绘图函数

    def plot_color_grid(df):
        宽度 = 1
        高度 = 1
        行数 = int(df.color.size ** 0.5)
        列数 = int(df.color.size ** 0.5)
        间隔 = 0.2
    
        步长 = 宽度 + 间隔
    
        x位置 = np.arange(0, 列数*步长, 步长)
        y位置 = np.arange(0, 行数*步长, 步长)
    
        fig = plt.figure(figsize=(20, 20))
        fig.patch.set_alpha(0)
        ax = plt.subplot(111, aspect='equal')
    
        ax.axis([0, 列数*步长 + 1, 0, 行数*步长 + 1])
    
        pat = []
    
        颜色索引 = -1
        for xi in x位置:
            for yi in y位置:
                颜色索引 += 1
                正方形 = Rectangle((yi, xi), 宽度, 高度, color=df.颜色[颜色索引])
                pat.append(正方形)
    
        pc = collections.PatchCollection(pat, match_original=True)
        ax.add_collection(pc)
    
        plt.axis('off')
        plt.show()
    

这是当我们将 pandas 数据框传递给函数时的结果:
使用matplotlib根据亮度绘制颜色。

请注意,figsize 非常大。如果它较小,而行数和列数这么大(在这种情况下为71),那么一些间隔开始消失或变得不一致。这也可以通过调整间隔大小、正方形路径尺寸、使用浮点数微调 figsize 来解决。

  1. 向数据框添加一个新列,用于HSP计算,例如:
    color_df["HSP"] = color_df.颜色.apply(lambda x: ((0.299 * x[0]) + (0.587 * x[1]) + (0.114 * x[2])) ** 0.5)
    

其中 "x" 显然是一个元组(R、G、B)

  1. 最后,我们根据这个新的 "HSP" 列对值进行排序并将它们传递给函数
    color_df = color_df.sort_values(by=['HSP'], ascending=True, ignore_index=True)
    

然后我们得到这个结果:
使用matplotlib根据亮度绘制颜色。

在参考文章中,它看起来像这样:
使用matplotlib根据亮度绘制颜色。

英文:

After digging and testing for a couple of days, I think I managed to achieve what I wanted so I'm sharing my results here in case someone else is trying to do something similar. Basically I was using a combination of the code this article and this thread.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.collections as collections
from matplotlib.patches import Rectangle
  1. Generate the random colors. First, pick the desired number of colors and then get the power of the rounded square root of this number. Do this to get a number that has an integer square root to get a perfect WIDTH x HEIGHT grid later on.

    desired_no_colors = 5000
    no_colors = round(np.sqrt(desired_no_colors))**2
    # Generate colors
    color_list = np.array([(np.random.choice(range(256), size=3)) for _ in np.arange(no_colors)])
    color_list = color_list / 255 # Convert values to 0-1 range
    
  2. Create a pandas dataframe with that list

    color_df = pd.DataFrame({'color': list(color_list)})

  3. Define the plotting function

    def plot_color_grid(df):
        width = 1
        height = 1
        nrows = int(df.color.size ** 0.5)
        ncols = int(df.color.size ** 0.5)
        gap = 0.2
    
        step = width + gap
    
        x_positions = np.arange(0, ncols*step, step)
        y_positions = np.arange(0, nrows*step, step)
    
        fig = plt.figure(figsize=(20, 20))
        fig.patch.set_alpha(0)
        ax = plt.subplot(111, aspect='equal')
    
        ax.axis([0, ncols*step + 1, 0, nrows*step + 1])
    
        pat = []
    
        color_index = -1
        for xi in x_positions:
            for yi in y_positions:
                color_index += 1
                sq = Rectangle((yi, xi), width, height, color=df.color[color_index])
                pat.append(sq)
    
    
        pc = collections.PatchCollection(pat, match_original=True)
        ax.add_collection(pc)
    
        plt.axis('off')
        plt.show()
    

and this is the result when we feed the function the pandas dataframe:
使用matplotlib根据亮度绘制颜色。

Notice that the figsize is pretty big. If it's smaller and the number of rows and columns is this big (71 in this case) then some of the gaps start disappearing or becoming inconsistent in size. This could also be resolved by fiddling around with the gap size, the Rectangle patch dimensions, fine tuning figsize with flot numbers.

  1. Add a new column to the DataFrame with values for HSP calculations for example.

    color_df["HSP"] = color_df.color.apply(lambda x: ((0.299 * x[0]) + (0.587 * x[1]) + (0.114 * x[2])) ** 0.5)
    

where "x" is apparently a tuple (R, G, B)

  1. And finally we sort the values by this new "HSP" column and pass them to the function

    color_df = color_df.sort_values(by=['HSP'], ascending=True, ignore_index=True)
    

and we get this:
使用matplotlib根据亮度绘制颜色。

which, in the reference article, looks like this:
使用matplotlib根据亮度绘制颜色。

huangapple
  • 本文由 发表于 2023年5月14日 02:30:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244317.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定