Search code examples
pythonpython-3.xdictionarymatplotlibcolor-scheme

Indexing a dictionary by passing a list


I'm trying to plot a data frame using colors stored in a dictionary. This code works:

import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame(np.random.randn(100, 4), index=range(100), columns=list('ABCD'))
df = df + [-2, 0, 2, 4]
x = list(range(100, 1100, 10))
clrhex = {'abcd':'#FFA500', 'efgh':'#FF0000','ijkl':'#000000','mnop':'#6495ED'}

plt.plot(x, df, color=[clrhex['abcd'], clrhex['efgh'], clrhex['ijkl'], clrhex['mnop']])
plt.show()

but I'd like to make this shorter by indexing the dictionary with a list. This:

plt.plot(x, df, color=clrhex['abcd', 'efgh', 'ijkl', 'mnop'])

gives the following error message:

Invalid RGBA argument

How can I get multiple values from a dictionary ?


Solution

  • If you are using matplotlib > 1.5, using set_color_cycle will bring up a depreciation message:

    c:\Python27\lib\site-packages\matplotlib\cbook\deprecation.py:106:
    MatplotlibDeprecationWarning: The set_color_cycle attribute was deprecated in version 1.5. Use set_prop_cycle instead.

    So, using set_prop_cycle you can do:

    df = pd.DataFrame(np.random.randn(100, 4), index=range(100), columns=list('ABCD'))
    df = df + [-2, 0, 2, 4]
    x = list(range(100, 1100, 10))
    clrhex = {'abcd':'#FFA500', 'efgh':'#FF0000','ijkl':'#000000','mnop':'#6495ED'}
    
    plt.gca().set_prop_cycle('color', [clrhex[i] for i in ['abcd', 'efgh', 'ijkl', 'mnop']])
    plt.plot(x, df)
    
    plt.show()
    

    The advantage of using set_prop_cycle is that you can use it with other things not just color, i.e. linestyles, or linewidths. Below is some modified code that shows how to change both the color and the linewidths (if you ever wanted to), and uses the object oriented API:

    from cycler import cycler
    
    df = pd.DataFrame(np.random.randn(100, 4), index=range(100), columns=list('ABCD'))
    df = df + [-2, 0, 2, 4]
    x = list(range(100, 1100, 10))
    clrhex = {'abcd':'#FFA500', 'efgh':'#FF0000','ijkl':'#000000','mnop':'#6495ED'}
    
    fig, ax = plt.subplots()
    
    ax.set_prop_cycle(cycler('color', [clrhex[i] for i in ['abcd', 'efgh', 'ijkl', 'mnop']]) + 
        cycler('lw', [1,2,3,4]))
    
    ax.plot(x, df)
    
    plt.show()
    

    Which gives:

    enter image description here