Colorspaces in three dimensions

Colorspaces.
Why so many?
Nobody knows.

As a part of my desire to recreate an image with methods that make no sense (for which I will hopefully muster up the courage required to blog about) I created 3D plots of the RGB and HSV colorspaces, and animated them for your viewing pleasure.

The program creates an evenly spaced 3D mesh grid of a cube, and by iterating on all the points it creates two nx3 arrays with the color information of each point using their coordinates. Colorsys is used for the RGB to HSV conversion.

Code

I took the easy road for the animation, saving the individual frames and making the video using ffmpeg:

Warning: use it on an empty folder because it removes pngs with a wildcard.

python3 ../c3d.py && ffmpeg -framerate 13 -f image2 -i ./HSV%03d.png -c:v libvpx -pix_fmt yuva420p -b:v 1.4M -auto-alt-ref 0 -vf scale=500:-1 HSV.webm && ffmpeg -framerate 13 -f image2 -i ./RGB%03d.png -c:v libvpx -pix_fmt yuva420p -b:v 1.4M -auto-alt-ref 0 -vf scale=500:-1 RGB.webm && rm ./RGB*.png && rm ./HSV*.png
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
import itertools
import colorsys
 
 
num = 8
size = 20
 
ds=True
 
x = np.linspace(0,255,num)
y = np.linspace(0,255,num)
z = np.linspace(0,255,num)
coord = np.linspace(0,255,num)
 
xv, yv, zv = np.meshgrid(coord,coord,coord)
xv = xv.flatten()
yv = yv.flatten()
zv = zv.flatten()
 
c_rgb = np.zeros([xv.size, 3])
c_hsv = np.zeros([xv.size, 3])
for i in range(xv.size):
    c_rgb[i,:] = np.array([xv[i], yv[i], zv[i]])/255.0
    c_hsv[i,:] = colorsys.hsv_to_rgb(xv[i]/255.0, yv[i]/255.0, zv[i]/255.0)
 
fnameind = 1
for i in range(-45,360-45,4):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(xv, yv, zv, s=size, c=c_rgb, depthshade=ds)
 
    ax.set_xlabel("R")
    ax.set_ylabel("G")
    ax.set_zlabel("B")
    ax.set_aspect('equal')
    ax.view_init(elev = 20, azim=i)
 
    plt.savefig('RGB' + str(fnameind).zfill(3) + '.png')
    plt.close(fig)
 
    fig2 = plt.figure()
    ax = fig2.add_subplot(111, projection='3d')
    ax.scatter(xv, yv, zv, s=size, c=c_hsv, depthshade=ds)
 
    ax.set_xlabel("H")
    ax.set_ylabel("S")
    ax.set_zlabel("V")
    ax.set_aspect('equal')
    ax.view_init(elev = 20, azim=i)
 
    plt.savefig('HSV' + str(fnameind).zfill(3) + '.png')
    plt.close(fig2)
 
    fnameind += 1