英文:
Plotting colors by brightness with matplotlib
问题
我想从这个事实开始,这不是一个关于如何确定颜色亮度的问题!
所以,我的问题是,我正在寻找一种方法来按颜色的亮度排列一组颜色。我有一个函数,它使用所有在这里提到的方法以及更多方法来计算亮度__这里__。这是一篇很棒的文章,几乎完全符合我所需的,但有几件事情我不太确定,所以将它作为示例会帮助我很多,可以更好地解释我试图实现的目标。
我想使用__matplotlib.pyplot__构建整个图表,而不是使用bokeh。Bokeh做得很好,但我需要与项目中的其他元素保持一致,所以我需要使用matplotlib重新构建它。我尝试了一些方法,但无法得到我想要的结果。
此外,如果我能够不按照文章中的方式创建图表,而是__垂直排列__它,类似于__这里的答案中的答案,具体来说,是___Petr Hurtak___和___Kal___的答案,只是在一个__正方形__内进行,而不是像他们所做的那样使用一个__细长的垂直矩形。
英文:
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.
答案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"));
您还可以按照以下方式将它们显示为网格,尽管在较高分辨率下速度较慢:
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");
如果您希望在浏览器中直接尝试,请使用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"));
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");
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
以下是您提供的内容的翻译:
-
生成随机颜色。首先,选择所需的颜色数量,然后获取该数量的四舍五入的平方根的幂。这样做是为了获得一个具有整数平方根的数字,以便后面得到一个完美的宽度 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范围
-
使用该列表创建一个 pandas 数据框
color_df = pd.DataFrame({'颜色': list(color_list)})
-
定义绘图函数
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()
请注意,figsize 非常大。如果它较小,而行数和列数这么大(在这种情况下为71),那么一些间隔开始消失或变得不一致。这也可以通过调整间隔大小、正方形路径尺寸、使用浮点数微调 figsize 来解决。
- 向数据框添加一个新列,用于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)
- 最后,我们根据这个新的 "HSP" 列对值进行排序并将它们传递给函数
color_df = color_df.sort_values(by=['HSP'], ascending=True, ignore_index=True)
英文:
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
-
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
-
Create a pandas dataframe with that list
color_df = pd.DataFrame({'color': list(color_list)})
-
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:
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.
-
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)
-
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论