How could I get a different pie chart color? I have a data set about 20 categories and it could be even larger. When I create a pie chart, some wedge have same color, so I wonder is there a way that I can have all colors different in my pie charts' wedge? Thanks!
Asked
Active
Viewed 4,921 times
1
-
1Does [this](https://stackoverflow.com/q/4805048/8881141) or [this](https://stackoverflow.com/q/16006572/8881141) answer your question? The cmap option is probably the best way for an unknown n although the colors might become quite similar with a high n number. – Mr. T Sep 02 '18 at 07:00
-
Does [this](https://matplotlib.org/1.5.0/examples/pie_and_polar_charts/pie_demo_features.html) answer your question? Please check out the `color=[colorlist]` option. – tif Sep 02 '18 at 12:14
1 Answers
4
20 Colors is exactly the limits of what you can achieve through categorical/qualitative colormaps in matplotlib. Currently matplotlib provides the tab20
, tab20b
, tab20c
colormaps.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randint(50,200, size=20)
fig = plt.figure()
with plt.style.context({"axes.prop_cycle" : plt.cycler("color", plt.cm.tab20.colors)}):
ax = fig.add_subplot(121, aspect="equal")
ax.pie(data)
with plt.style.context({"axes.prop_cycle" : plt.cycler("color", plt.cm.tab20c.colors)}):
ax2 = fig.add_subplot(122, aspect="equal")
ax2.pie(data)
plt.show()
For more colors one can of course also use different colormaps, but those will generally result in pretty similar colors next to each other. E.g. for a pie chart with 30 different colors we may use the nipy_spectral
or the CMRmap
colormap.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randint(50,200, size=30)
fig = plt.figure()
cc = plt.cycler("color", plt.cm.nipy_spectral(np.linspace(0,.9,len(data))))
with plt.style.context({"axes.prop_cycle" : cc}):
ax = fig.add_subplot(121, aspect="equal")
ax.pie(data)
cc = plt.cycler("color", plt.cm.CMRmap(np.linspace(0,0.9,len(data))))
with plt.style.context({"axes.prop_cycle" : cc}):
ax2 = fig.add_subplot(122, aspect="equal")
ax2.pie(data)
plt.show()
So one may add another dimension. Choosing some colors from any colormap and creating different luminosity levels for each of them. This is essentially shown in this answer. Here, in order to get e.g. 30 different colors we may choose 6 colors and for each 5 luminosity levels.
import matplotlib.pyplot as plt
import numpy as np
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
data = np.random.randint(50,200, size=30)
fig = plt.figure()
cc = plt.cycler("color", categorical_cmap(6, 5, cmap="tab10").colors)
with plt.style.context({"axes.prop_cycle" : cc}):
ax = fig.add_subplot(121, aspect="equal")
ax.pie(data)
cc = plt.cycler("color",
categorical_cmap(6, 5, cmap="gist_rainbow", continuous=True).colors)
with plt.style.context({"axes.prop_cycle" : cc}):
ax2 = fig.add_subplot(122, aspect="equal")
ax2.pie(data)
plt.show()

ImportanceOfBeingErnest
- 321,279
- 53
- 665
- 712