Using colour and the dominant_wavelength definition, it is relatively straightforward to achieve in 3 or 4 lines:
# 6 Random RGB values, assuming that they are "sRGB" encoded.
RGB = np.random.random([6, 3])
# Converted to "CIE xy" chromaticity coordinates.
xy = colour.XYZ_to_xy(colour.sRGB_to_XYZ(RGB, apply_cctf_decoding=False))
whitepoint = colour.models.RGB_COLOURSPACE_sRGB.whitepoint
# The dominant wavelength computation call, "wl" represents the
# wavelengths, "f_i" and "s_i" the first and second intersection
# on the spectral locus.
# A negative dominant wavelength means that the line of purple is
# where the intersection occurred
wl, f_i, s_i = colour.dominant_wavelength(xy, whitepoint)
# ****************************************************************************
# Plotting the data in the "CIE 1931 Chromaticity Diagram".
figure, axes = colour.plotting.plot_chromaticity_diagram_CIE1931(
diagram_opacity=0.15, standalone=False
)
cycle = colour.plotting.colour_cycle()
for i in range(len(f_i)):
point_colour = next(cycle)
axes.plot(xy[i, 0], xy[i, 1], "o", color=point_colour)
axes.plot(
[whitepoint[0], f_i[i][0]],
[whitepoint[1], f_i[i][1]],
color=point_colour,
)
# Plotting the data as colour swatches.
# !!! Note that your display most likely cannot represent
# them properly, they are out-of-gamut !!!
RGB_wl = colour.XYZ_to_sRGB(colour.xy_to_XYZ(f_i), apply_cctf_encoding=False)
colour_swatches = [
colour.plotting.ColourSwatch(a, wl[i])
for i, a in enumerate(colour.cctf_encoding(RGB))
] + [
colour.plotting.ColourSwatch(a, wl[i])
for i, a in enumerate(colour.cctf_encoding(RGB_wl))
]
colour_swatches = [
swatch
for pairs in zip(
colour_swatches[0 : len(colour_swatches) // 2],
colour_swatches[len(colour_swatches) // 2 :],
)
for swatch in pairs
]
colour.plotting.plot_multi_colour_swatches(
colour_swatches,
columns=len(RGB),
compare_swatches="Diagonal",
)
Google Colab notebook if you want to test live: https://colab.research.google.com/drive/1cxhLBh2JtzVh8XUfe0-oJ4YDCyrW7mD5?usp=sharing
