Last active
December 20, 2025 19:44
-
-
Save bastibe/ae4641b17b457eea6e9d0d470bbadbdb to your computer and use it in GitHub Desktop.
Plot renders of sRGB sweep in chromaticity diagram
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import colour.models | |
| import colour.plotting | |
| import pathlib | |
| from matplotlib import pyplot | |
| from PIL import Image | |
| def plot_chromaticity_image(filename): | |
| image = Image.open(filename) | |
| traces = extract_traces(image) | |
| fig, ax = colour.plotting.diagrams.plot_chromaticity_diagram(show_diagram_colours=False, show=False) | |
| srgb = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]] | |
| xy = colour.XYZ_to_xy(colour.sRGB_to_XYZ(srgb)) | |
| ax.scatter(xy[:, 0], xy[:, 1], marker='o', c=srgb, label='sRGB') | |
| for trace in traces: | |
| trace = [t for t in trace if sum(t) > 0] # skip [0, 0, 0] | |
| xy = colour.XYZ_to_xy(colour.sRGB_to_XYZ(trace)) | |
| ax.plot(xy[:, 0], xy[:, 1], '-', color='lightgray', alpha=0.3) | |
| ax.scatter(xy[:, 0], xy[:, 1], marker='o', s=5, c=trace) | |
| ax.set(xlim=(-0.1, 0.8), ylim=(-0.1, 0.9), aspect='equal') | |
| ax.set(title=filename.stem) | |
| return fig, ax | |
| def plot_oklch_image(filename): | |
| image = Image.open(filename) | |
| traces = extract_traces(image) | |
| fig, ax = pyplot.subplots() | |
| srgb = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0], | |
| [1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]] | |
| oklch = colour.Oklab_to_Oklch(colour.XYZ_to_Oklab(colour.sRGB_to_XYZ(srgb))) | |
| ax.scatter([1.02]*len(oklch), oklch[:, 2], marker='o', c=srgb, label='sRGB') | |
| for trace in traces: | |
| trace = [t for t in trace if sum(t) > 0] # skip [0, 0, 0] | |
| oklch = colour.Oklab_to_Oklch(colour.XYZ_to_Oklab(colour.sRGB_to_XYZ(trace))) | |
| ax.plot(oklch[:, 0], oklch[:, 2], '-', color='lightgray', alpha=0.3) | |
| ax.scatter(oklch[:, 0], oklch[:, 2], marker='o', s=5, c=trace) | |
| ax.set(xlim=(0.0, 1.04), xlabel='Oklch L (luminance)', | |
| ylim=(360.0, 0.0), ylabel='Oklch h (hue angle)') | |
| ax.set(title=filename.stem) | |
| return fig, ax | |
| def extract_traces(image): | |
| tl = 147, 111 | |
| br = 1780, 916 | |
| num_boxes = 51, 19 | |
| box_size = (br[0] - tl[0]) / num_boxes[0], (br[1] - tl[1]) / num_boxes[1] | |
| lines = [] | |
| for box_y in range(num_boxes[1]): | |
| line = [] | |
| for box_x in range(num_boxes[0]): | |
| px_x = tl[0] + box_x * box_size[0] + box_size[0] / 2 | |
| px_y = tl[1] + box_y * box_size[1] + box_size[1] / 2 | |
| color = image.getpixel((int(px_x), int(px_y))) | |
| color = tuple(c / 255 for c in color) | |
| line.append(color) | |
| lines.append(line) | |
| return lines | |
| if __name__ == "__main__": | |
| for filename in pathlib.Path('.').glob('*.png'): | |
| fig, ax = plot_chromaticity_image(filename) | |
| fig.savefig(filename.stem + '_chromaticity.svg') | |
| pyplot.close(fig) | |
| fig, ax = plot_oklch_image(filename) | |
| fig.savefig(filename.stem + '_oklch.svg') | |
| pyplot.close(fig) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Feel free to use this script any way you please. I place it in the public domain.