Skip to content

Instantly share code, notes, and snippets.

@bastibe
Last active December 20, 2025 19:44
Show Gist options
  • Select an option

  • Save bastibe/ae4641b17b457eea6e9d0d470bbadbdb to your computer and use it in GitHub Desktop.

Select an option

Save bastibe/ae4641b17b457eea6e9d0d470bbadbdb to your computer and use it in GitHub Desktop.
Plot renders of sRGB sweep in chromaticity diagram
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)
@bastibe
Copy link
Author

bastibe commented Dec 20, 2025

Feel free to use this script any way you please. I place it in the public domain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment