Построение цветов по яркости с помощью matplotlib

Хочу начать с того, что это НЕ вопрос о том, как определить яркость цвета!

Итак, моя проблема в том, что я ищу способ упорядочить набор цветов по их яркости. У меня есть функция, которая вычисляет яркость всеми методами, упомянутыми здесь и другими. Это отличная статья, которая делает почти то, что мне нужно, но я не уверен в нескольких вещах, поэтому наличие ее в качестве примера очень помогло бы мне объяснить, чего я пытаюсь достичь.

Я хочу построить весь сюжет со всеми цветами, используя matplotlib.pyplot вместо боке. Боке отлично справляется со своей задачей, но мне нужно согласовать его с другими вещами в моем проекте, поэтому мне нужно реконструировать его с помощью matplotlib. Я попробовал несколько методов, но не смог добиться желаемых результатов.

Кроме того, было бы здорово, если бы вместо того, чтобы создавать сюжет, как он создан в статье, я мог бы создать его вертикально, как в ответах здесь, точнее, в ответах Петра Хуртака и Каля, только сделайте это в виде квадрата вместо использования вытянутого вертикального прямоугольника, как это сделали они.

Полезные изображения, взятые из упомянутых статей:

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
0
0
100
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

После копания и тестирования в течение пары дней, я думаю, мне удалось добиться того, чего я хотел, поэтому я делюсь своими результатами здесь на случай, если кто-то еще попытается сделать что-то подобное. По сути, я использовал комбинацию кода этой статьи и этой ветки.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.collections as collections
from matplotlib.patches import Rectangle
  1. Сгенерируйте случайные цвета. Сначала выберите желаемое количество цветов, а затем получите степень округленного квадратного корня из этого числа. Сделайте это, чтобы получить число, имеющее целочисленный квадратный корень, чтобы позже получить идеальную сетку WIDTH x HEIGHT.

    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. Создайте фрейм данных pandas с этим списком

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

  3. Определите функцию построения графика

    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()
    

и это результат, когда мы передаем функции фрейм данных pandas:

Обратите внимание, что figsize довольно большой. Если он меньше, а количество строк и столбцов такое большое (в данном случае 71), то некоторые пробелы начинают исчезать или становятся несовместимыми по размеру. Это также можно решить, повозившись с размером промежутка, размерами прямоугольного патча, точной настройкой figsize с номерами флота.

  1. Добавьте новый столбец в DataFrame со значениями, например, для вычислений HSP.

    color_df["HSP"] = color_df.color.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)
    

и мы получаем это:

который в справочной статье выглядит так:

Попробуйте использовать ascending=False внутри color_df.sort_values...

Joao_PS 15.05.2023 03:20

Цвет позволит сделать это, также используя более однородное для восприятия цветовое пространство, например. JzAzBz, Оклаб, 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, если вы хотите попробовать прямо в браузере: https://colab.research.google.com/drive/1SD-ZU1clsHgHFyC0gpIP2fK9xBvYX-oS?usp=sharing

Я знаю о библиотеке цветов, но, поскольку я делаю свои собственные расчеты, мне нужно построить ее самостоятельно, поэтому я специально попросил способ сделать это с помощью matplotlib. Ваш метод - хорошая альтернатива, и даже если он не работает в моем случае, он может помочь кому-то другому.

Aleks K. 17.05.2023 10:39

Я не указывал это, но две приведенные выше процедуры построения графиков используют Matplotlib.

Kel Solaar 17.05.2023 18:53

Другие вопросы по теме