Search code examples
pythonmatlabnumpyoctavehsv

Translating Matlab (Octave) group coloring code into python (numpy, pyplot)


I want to translate the following group coloring octave function to python and use it with pyplot.

Function input:
x - Data matrix (m x n)
a - A parameter.
index - A vector of size "m" with values in range [: a]
(For example if a = 4, index can be [random.choice(range(4)) for i in range(m)]

The values in "index" indicate the number of the group the "m"th data point belongs to. The function should plot all the data points from x and color them in different colors (Number of different colors is "a").

The function in octave:

p = hsv(a); % This is a x 3 metrix
colors = p(index, :); % ****This is m x 3 metrix****
scatter(X(:,1), X(:,2), 10, colors);

I couldn't find a function like hsv in python, so I wrote it myself (I think I did..):

 p = colors.hsv_to_rgb(numpy.column_stack((
numpy.linspace(0, 1, a), numpy.ones((a ,2)) )) )

But I can't figure out how to do the matrix selection p(index, :) in python (numpy). Specially because the size of "index" is bigger then "a".

Thanks in advance for your help.


Solution

  • So, you want to take an m x 3 of HSV values, and convert each row to RGB?

    import numpy as np
    import colorsys
    mymatrix = np.matrix([[11,12,13],
                          [21,22,23],
                          [31,32,33]])
    
    def to_hsv(x):
        return colorsys.rgb_to_hsv(*x)
    
    #Apply the to_hsv function to each matrix row.
    print np.apply_along_axis(to_hsv, axis=1, arr=mymatrix)
    

    This produces:

    [[  0.5   0.   13. ]
     [  0.5   0.   23. ]
     [  0.5   0.   33. ]]
    

    Follow through on your comment:

    If I understand you have a matrix p that is an a x 3 matrix, and you want to randomly select rows from the matrix over and over again, until you have a new matrix that is m x 3?

    Ok. Let's say you have a matrix p defined as follows:

    a = 5
    p = np.random.randint(5, size=(a, 3))
    

    Now, make a list of random integers between the range 0 -> 3 (index starts at 0 and ends to a-1), That is m in length:

    m = 20
    index = np.random.randint(a, size=m)
    

    Now access the right indexes and plug them into a new matrix:

    p_prime = np.matrix([p[i] for i in index])
    

    Produces a 20 x 3 matrix.