Skip to content

Pb with cl.interp on colors scale #9

Open

Description

@yoyonel
In [294]: import colorlover as cl              

In [295]: cl                                   
Out[295]: <module 'colorlover' from '/home/latty/.virtualenvs/screenpulse-unittest/local/lib/python2.7/site-packages/colorlover/__init__.pyc'>                                                

In [296]: colormaps = cl.scales['7']['qual']['Dark2']                                          

In [297]: colormaps                            
Out[297]:                                      
['rgb(27,158,119)',                            
 'rgb(217,95,2)',                              
 'rgb(117,112,179)',                           
 'rgb(231,41,138)',                            
 'rgb(102,166,30)',                            
 'rgb(230,171,2)',                             
 'rgb(166,118,29)']                            

In [298]: cl.interp(colormaps, 11)             
---------------------------------------------------------------------------                    
IndexError                                Traceback (most recent call last)                    
<ipython-input-298-946770f2b787> in <module>() 
----> 1 cl.interp(colormaps, 11)               

/home/latty/.virtualenvs/screenpulse-unittest/local/lib/python2.7/site-packages/colorlover/__init__.pyc in interp(scl, r)                                                                     
   1821         c_i = int(i*math.floor(SCL_FI)/round(r[-1])) # start color index               
   1822         hsl_o = rgb_to_hsl( scl[c_i] ) # convert rgb to hls                            
-> 1823         hsl_f = rgb_to_hsl( scl[c_i+1] )                                               
   1824         section_min = c_i*r[-1]/SCL_FI 
   1825         section_max = (c_i+1)*(r[-1]/SCL_FI)                                           

IndexError: list index out of range            

this bug is not stable, here for example:

In [310]: cl.interp(colormaps, 10)
Out[310]: 
['hsl(162.0, 70.0%, 36.0%)',
 'hsl(70.6666666667, 88.6666666667%, 40.0%)',
 'hsl(72.3333333333, 75.3333333333%, 47.0%)',
 'hsl(167.0, 30.0%, 57.0%)',
 'hsl(275.0, 62.6666666667%, 54.3333333333%)',
 'hsl(248.666666667, 75.6666666667%, 48.0%)',
 'hsl(88.0, 69.0%, 38.0%)',
 'hsl(58.6666666667, 88.3333333333%, 42.6666666667%)',
 'hsl(29.3333333333, 107.666666667%, 47.3333333333%)',
 'hsl(38.0, 70.0%, 38.0%)']

In [311]: cl.interp(colormaps, 11)             
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-311-946770f2b787> in <module>() 
----> 1 cl.interp(colormaps, 11)               

/home/latty/.virtualenvs/screenpulse-unittest/local/lib/python2.7/site-packages/colorlover/__init__.pyc in interp(scl, r)
   1821         c_i = int(i*math.floor(SCL_FI)/round(r[-1])) # start color index
   1822         hsl_o = rgb_to_hsl( scl[c_i] ) # convert rgb to hls
-> 1823         hsl_f = rgb_to_hsl( scl[c_i+1] )
   1824         section_min = c_i*r[-1]/SCL_FI
   1825         section_max = (c_i+1)*(r[-1]/SCL_FI)

IndexError: list index out of range

In [312]: cl.interp(colormaps, 15)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-312-e3b4fde92ac0> in <module>()
----> 1 cl.interp(colormaps, 15)

/home/latty/.virtualenvs/screenpulse-unittest/local/lib/python2.7/site-packages/colorlover/__init__.pyc in interp(scl, r)
   1821         c_i = int(i*math.floor(SCL_FI)/round(r[-1])) # start color index
   1822         hsl_o = rgb_to_hsl( scl[c_i] ) # convert rgb to hls
-> 1823         hsl_f = rgb_to_hsl( scl[c_i+1] )
   1824         section_min = c_i*r[-1]/SCL_FI
   1825         section_max = (c_i+1)*(r[-1]/SCL_FI)

IndexError: list index out of range

In [313]: cl.interp(colormaps, 16)
Out[313]: 
['hsl(162.0, 70.0%, 36.0%)',
 'hsl(107.2, 81.2%, 38.4%)',
 'hsl(52.4, 92.4%, 40.8%)',
 'hsl(-2.4, 103.6%, 43.2%)',
 'hsl(110.2, 57.2%, 51.0%)',
 'hsl(167.0, 30.0%, 57.0%)',
 'hsl(223.8, 2.8%, 63.0%)',
 'hsl(296.6, 69.2%, 53.8%)',
 'hsl(361.4, 88.8%, 52.2%)',
 'hsl(426.2, 108.4%, 50.6%)',
 'hsl(88.0, 69.0%, 38.0%)',
 'hsl(-8.4, 65.0%, 32.0%)',
 'hsl(-104.8, 61.0%, 26.0%)',
 'hsl(-201.2, 57.0%, 20.0%)',
 'hsl(17.6, 115.4%, 49.2%)',
 'hsl(0.0, 127.0%, 52.0%)']

Activity

  1. yoyonel commented on Oct 2, 2017

    @yoyonel
    Author

    I propose a (new) implementation with scipy/numpy implementation for interp:

    def interp(scl, r):
        ''' Interpolate a color scale "scl" to a new one with length "r"
            Fun usage in IPython notebook:
            HTML( to_html( to_hsl( interp( cl.scales['11']['qual']['Paired'], 5000 ) ) ) ) '''
        def rgb_to_hsl(rgb):
            ''' Adapted from M Bostock's RGB to HSL converter in d3.js
                https://github.com/mbostock/d3/blob/master/src/color/rgb.js '''
            r, g, b = float(rgb[0]) / 255.0, \
                      float(rgb[1]) / 255.0, \
                      float(rgb[2]) / 255.0
            mx = max(r, g, b)
            mn = min(r, g, b)
            h = s = l = (mx + mn) / 2
            if mx == mn:  # achromatic
                h = 0
                s = 0 if 0 < l < 1 else h
            else:
                d = mx - mn
                s = d / (mx + mn) if l < 0.5 else d / (2 - mx - mn)
                if mx == r:
                    h = (g - b) / d + (6 if g < b else 0)
                elif mx == g:
                    h = (b - r) / d + 2
                else:
                    h = r - g / d + 4
    
            return int(round(h * 60, 4)), int(round(s * 100, 4)), int(round(l * 100, 4))
    
        # convert str RGB to numeric list of tuples
        scl = cl.to_numeric(scl)
        # convert RGB to HSL colormap (allow to interpolate linearly after)
        shsl = map(rgb_to_hsl, scl)
        nb_composants = len(scl[0])
        assert nb_composants == 3
        range_shsl = np.arange(len(shsl))
        interp_range_shsl = np.linspace(0, len(shsl)-1, num=r, endpoint=True)
        scl_interps = [
            interpolate.interp1d(range_shsl, map(itemgetter(composant), shsl))(interp_range_shsl)
            for composant in range(nb_composants)
        ]
    
        interp_c = map(
            lambda hsl: 'hsl' + str(hsl),
            zip(*scl_interps)
        )
    
        return cl.to_hsl(interp_c)
    

    I think it's more simple and seems to be more stable (not buggy :p).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions