Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use correct cmap colors in nested pie chart in matplotlib

How do I use the correct np.array of cmap that the inside colors correspond to shades of the outside colors in a nested pie chart in matplotlib?

I tried using different arrays of cmap, but I don't understand how the arrays get transformed into cmap colors.

import numpy as np
import matplotlib.pyplot as plt

y =np.array([17, 16, 10, 8 ,6, 5, 5, 4, 3,  17 ,2 ,1, 1, 3, 2 ])
x = np.array([74 ,21 ,5])

fig, ax = plt.subplots()

size = 0.3

cmap = plt.get_cmap("tab20c")

outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap(np.array([1, 2, 5, 6, 9, 10]))

ax.pie(x, radius=1, colors=outer_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.pie(y, radius=1-size, colors=inner_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()

enter image description here

I want the inside colors to be shades of the outside colors (greenish, blueish and orangish), but I have no idea how to change them accordingly.

Thanks!

like image 215
tina K Avatar asked Aug 30 '19 05:08

tina K


People also ask

What is the default CMAP in Matplotlib?

The new default colormap used by matplotlib. cm. ScalarMappable instances is 'viridis' (aka option D).

What is the use of CMAP in Matplotlib?

The set_cmap() function in pyplot module of matplotlib library is used to set the default colormap, and applies it to the current image if any. Parameters: cmap : This parameter is the colormap instance or the name of a registered colormap.


1 Answers

The tab20c colormap has 4 shades per hue. So it will not be possible to use that for 9 subcategories.

A. Extend the number of shades per hue

Taking the categorical_cmap from matplotlib generic colormap from tab10 one get get more shades per hue.

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

def categorical_cmap(nc, nsc, cmap="tab10", continuous=False):
    if nc > plt.get_cmap(cmap).N:
        raise ValueError("Too many categories for colormap.")
    if continuous:
        ccolors = plt.get_cmap(cmap)(np.linspace(0,1,nc))
    else:
        ccolors = plt.get_cmap(cmap)(np.arange(nc, dtype=int))
    cols = np.zeros((nc*nsc, 3))
    for i, c in enumerate(ccolors):
        chsv = matplotlib.colors.rgb_to_hsv(c[:3])
        arhsv = np.tile(chsv,nsc).reshape(nsc,3)
        arhsv[:,1] = np.linspace(chsv[1],0.25,nsc)
        arhsv[:,2] = np.linspace(chsv[2],1,nsc)
        rgb = matplotlib.colors.hsv_to_rgb(arhsv)
        cols[i*nsc:(i+1)*nsc,:] = rgb       
    cmap = matplotlib.colors.ListedColormap(cols)
    return cmap

y =np.array([17, 16, 10, 8 ,6, 5, 5, 4, 3,  17 ,2 ,1, 1, 3, 2 ])
x = np.array([74 ,21 ,5])

fig, ax = plt.subplots()

size = 0.3

cmap = categorical_cmap(3, 10)

outer_colors = cmap(np.array([0, 10, 20]))
ar = np.concatenate((np.arange(1,10), [13,15,17,19], [25,30]))
inner_colors = cmap(ar)

ax.pie(x, radius=1, colors=outer_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.pie(y, radius=1-size, colors=inner_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()

enter image description here

B. Use three different colormaps

Alternatively, one could use three different continuous colormaps, and take some of those colors.

import numpy as np
import matplotlib.pyplot as plt

y =np.array([17, 16, 10, 8 ,6, 5, 5, 4, 3, 17 ,2 ,1, 1, 3, 2 ])
x = np.array([74 ,21 ,5])

fig, ax = plt.subplots()

size = 0.3

cmap1 = plt.cm.Reds
cmap2 = plt.cm.Purples
cmap3 = plt.cm.Greens

outer_colors = [cmap1(.8), cmap2(.8), cmap3(.8)]
inner_colors = [*cmap1(np.linspace(.6, .1, 9)),
                *cmap2(np.linspace(.6, .2, 4)),
                *cmap3(np.linspace(.6, .2, 2))]

ax.pie(x, radius=1, colors=outer_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.pie(y, radius=1-size, colors=inner_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()

enter image description here

like image 92
ImportanceOfBeingErnest Avatar answered Sep 28 '22 19:09

ImportanceOfBeingErnest