Search code examples
pythonpandasmatplotlibcolorspie-chart

Change color of pie chart according to section label (pandas/matplotlib)


I am working from a DataFrame called plot_df that looks like this:

plot_df

                Country Visual Format                          $
0                 France       DEFAULT                    4.378900e+03
1                 France     DIGITAL3D                    1.170000e+02
2                 France        IMAX3D                    0.000000e+00
3              Hong Kong       DIGITAL                    1.061189e+07
4              Hong Kong     DIGITAL3D                    1.881850e+05
5                  India          DBOX                    1.137234e+06
6                  India       DIGIMAX                    2.653723e+06
7                  India       DIGITAL                    3.283665e+07
8                  Japan       DEFAULT                    5.819080e+07
9                  Japan       DIGIMAX                    8.193800e+06
10                Kuwait       DEFAULT                    6.130250e+04
11                Kuwait     DIGITAL3D                    1.099000e+03
12                Kuwait        IMAX3D                    1.057550e+04
13                Kuwait         MXP3D                    8.736000e+03
14              Malaysia       DIGIMAX                    2.941200e+04
15              Malaysia       DIGITAL                    2.590491e+06
16              Malaysia         MXP2D                    9.478000e+03
17                Mexico          4D3D                    3.806130e+06
18                Mexico     DIGIMAX3D                    0.000000e+00
19                Mexico       DIGITAL                    3.631979e+07
20                Mexico     DIGITAL3D                    7.510887e+06
21      Netherlands, The          4D3D                    4.435451e+04
22      Netherlands, The     DIGIMAX3D                    7.488704e+04
23      Netherlands, The       DIGITAL                    3.350028e+04
24      Netherlands, The     DIGITAL3D                    2.521642e+05
25      Netherlands, The         MXP3D                    3.298899e+04
26                  Peru       DIGITAL                    1.707998e+06
27                  Peru     DIGITAL3D                    1.030680e+05
28                  Peru         MXP2D                    3.961500e+04
29                  Peru         MXP3D                    4.077950e+04
30                  Peru           PLF                    1.310630e+05
31                 Spain     DIGIMAX3D                    7.717070e+03
32                 Spain       DIGITAL                    5.198949e+05
33                 Spain     DIGITAL3D                    2.494451e+04
34                 Spain         MXP3D                    1.025880e+04
35              Thailand       DIGITAL                    3.217920e+05
36                Turkey          4D3D                    5.433525e+04
37                Turkey       DIGITAL                    2.693310e+05
38                Turkey     DIGITAL3D                    6.161560e+05
39                Turkey         MXP3D                    4.168149e+04
40          UK & Ireland       DEFAULT                    1.170058e+06
41          UK & Ireland     DIGITAL3D                    1.755717e+05
42          UK & Ireland        IMAX3D                    1.065599e+05
43  United Arab Emirates       DEFAULT                    4.317666e+06
44  United Arab Emirates     DIGITAL3D                    2.808751e+04
45  United Arab Emirates        IMAX3D                    6.832500e+04

I am trying to create _ number of pie chart subplots. This is my code so far:

fig, axes = plt.subplots(nrows=int(np.ceil(plot_df.index.get_level_values(0).nunique()/3)), 
                         ncols=3, 
                         figsize=(15,15))
fig.tight_layout()
axes_list = [item for sublist in axes for item in sublist] 

for country in plot_df.index.get_level_values(0).unique():
    ax = axes_list.pop(0)
    plot_df.loc[(country, slice(None))].plot(kind='pie', 
                                             subplots=True,
                                             legend=False, 
                                             autopct='%1.1f%%',
                                             ax=ax)
    ax.set_title(country, fontweight='bold')
    ax.tick_params(
        bottom=False
    )
    ax.set_ylabel(ylabel=None)

for ax in axes_list:
    ax.remove()

My end result will look something like this:

end result

My question has to do with the colors assigned to each visual format. Every country has a different set of formats and this leads to inconsistent assignment of colors to labels. (For example, DIGITAL is BLUE in Hong Kong but is GREEN in India).

Is there a way to create a dictionary, with visual formats as keys and colors as values, and assign this dictionary to the pandas plot color parameter? Thanks.


Solution

  • You can use the colors parameter for pie charts. Since this takes an array, you'll have to create an array that corresponds to your input data for each plot.

    cdict = {'DIGITAL': 'r', 'DIGIMAX3D': 'y', 'DIGITAL3D': 'b', ...}
    
    for country in plot_df.index.get_level_values(0).unique():
        ax = axes_list.pop(0)
        df = plot_df.loc[(country, slice(None))]
        colors = [cdict[x] for x in df.index]  % colors based on index of input data
        df.plot(kind='pie', colors=colors, subplots=True, legend=False, autopct='%1.1f%%', ax=ax)