Home > Enterprise >  Plotting RGB colors using ratios
Plotting RGB colors using ratios

Time:01-29

I'm currently working on a project that requires plotting RGB colors as a figure. The colors are stored in a nx3 array where n is the number of colors and 3 is the RGB values.

For example:

colors = [[0.70248465, 0.10704011, 0.00900125], [0.0067905 , 0.27228963, 0.6428365 ], [0.00859376, 0.36948201, 0.18334154], [0.85125032, 0.65469019, 0.04035713]

Let's also say that I have an array that stores size ratios in respect of the first color.

For example:

ratios = [1,1/2,1/3,1/5]

What I want to do is to plot these colors but keeping the size ratios. My current function is:

def plot(colors):

    plt.imshow([colors])
    plt.axis('off')

    plt.show()

This plots the colors like this:

imshow

whereas I would like something like this:

enter image description here

CodePudding user response:

The following approach uses a ListedColormap. The ratios are multiplied by some sufficiently large factor, rounded and used as a repetition factor.

import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np

colors = [[0.70248465, 0.10704011, 0.00900125], [0.0067905, 0.27228963, 0.6428365], [0.00859376, 0.36948201, 0.18334154], [0.85125032, 0.65469019, 0.04035713]]

ratios = [1, 1/2, 1/3, 1/5]
ratios_int = (np.array(ratios) * 60).round().astype(int)

plt.imshow(np.repeat(np.arange(len(colors)), ratios_int).reshape(1, -1),
           cmap=ListedColormap(colors), # the given list of colors
           aspect=ratios_int.sum()/10)  # 1:10 aspect ratio for the image
plt.axis('off')
plt.show()

colors via ListedColormap

CodePudding user response:

This should do the trick:

EXPAND_BY = 30

expanded_colors = []
for c, r in zip(colors, ratios):
    expanded_colors  = [c] * int(EXPAND_BY * r)    
colors = expanded_colors

Be careful in choosing a value for EXPAND_BY. The greatest common denominator of the ratios is correct, but any large-ish value should give visually convincing results.

How does it work?

Imshow assumes each RGB triple it gets is one "pixel". This solution simply repeats each entry (pixel) according to its size ratio.

Probably not very memory efficient for larger data, but very code efficient - only a handful of additional lines :)

  •  Tags:  
  • Related