How to make MxN piechart graphs with one legend and remove Y axis names in Matplotlib

I have the following code:

import matplotlib.pyplot as plt plt.style.use('ggplot') import numpy as np np.random.seed(123456) import pandas as pd df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) f, axes = plt.subplots(1,4, figsize=(10,5)) for ax, col in zip(axes, df.columns): df[col].plot(kind='pie', autopct='%.2f', ax=ax, title=col, fontsize=10) ax.legend(loc=3) plt.ylabel("") plt.xlabel("") plt.show() 

What makes the following chart:

enter image description here

How can I do the following:

  • M = 2 x N = 2, the values โ€‹โ€‹of M and N may vary.
  • Delete y-title axis
  • Remove Legends
  • Save it to a file
+6
source share
1 answer

Several pie diagrams with a common legend

In my opinion, the easiest way to build things manually with matplotlib is to use the pandas data-building method in this case. This way you have more control. You can add a legend only to the first axes after building all your pie charts:

 import matplotlib.pyplot as plt import numpy as np np.random.seed(123456) import pandas as pd df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] fig, axes = plt.subplots(1,4, figsize=(10,5)) for ax, col in zip(axes, df.columns): ax.pie(df[col], labels=df.index, autopct='%.2f', colors=colors) ax.set(ylabel='', title=col, aspect='equal') axes[0].legend(bbox_to_anchor=(0, 0.5)) fig.savefig('your_file.png') # Or whichever format you'd like plt.show() 

enter image description here

Use pandas Build Methods Instead

However, if you prefer to use the charting method:

 import matplotlib.pyplot as plt import numpy as np np.random.seed(123456) import pandas as pd df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] fig, axes = plt.subplots(1,4, figsize=(10,5)) for ax, col in zip(axes, df.columns): df[col].plot(kind='pie', legend=False, ax=ax, autopct='%0.2f', title=col, colors=colors) ax.set(ylabel='', aspect='equal') axes[0].legend(bbox_to_anchor=(0, 0.5)) fig.savefig('your_file.png') plt.show() 

Both give the same results.


Rearrange a grid of subheadings

If you want to have 2x2 or another grid layout of plots, plt.subplots will return a 2D array of axes. Therefore, you will need to axes.flat over only axes.flat instead of axes .

For instance:

 import matplotlib.pyplot as plt import numpy as np np.random.seed(123456) import pandas as pd df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] fig, axes = plt.subplots(nrows=2, ncols=2) for ax, col in zip(axes.flat, df.columns): ax.pie(df[col], labels=df.index, autopct='%.2f', colors=colors) ax.set(ylabel='', title=col, aspect='equal') axes[0, 0].legend(bbox_to_anchor=(0, 0.5)) fig.savefig('your_file.png') # Or whichever format you'd like plt.show() 

enter image description here

Other grid layouts

If you want the grid layout to have more axes than the amount of data you have, you need to hide any axes that you donโ€™t overlap. For instance:

 import matplotlib.pyplot as plt import numpy as np np.random.seed(123456) import pandas as pd df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] fig, axes = plt.subplots(nrows=2, ncols=3) for ax in axes.flat: ax.axis('off') for ax, col in zip(axes.flat, df.columns): ax.pie(df[col], labels=df.index, autopct='%.2f', colors=colors) ax.set(ylabel='', title=col, aspect='equal') axes[0, 0].legend(bbox_to_anchor=(0, 0.5)) fig.savefig('your_file.png') # Or whichever format you'd like plt.show() 

enter image description here


Label omission

If you do not want the labels to be outside, omit the labels argument in pie . However, when we do this, we will need to create the legend by hand, passing it to artists and stickers for artists. This is also a good time to demonstrate the use of fig.legend to align one legend with a figure. In this case, we put the legend in the center:

 import matplotlib.pyplot as plt import numpy as np np.random.seed(123456) import pandas as pd df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] fig, axes = plt.subplots(nrows=2, ncols=2) for ax, col in zip(axes.flat, df.columns): artists = ax.pie(df[col], autopct='%.2f', colors=colors) ax.set(ylabel='', title=col, aspect='equal') fig.legend(artists[0], df.index, loc='center') plt.show() 

enter image description here

Percentage Transfer Labels Outside

Similarly, the radial position of percentage marks is controlled by pctdistance kwarg. Values โ€‹โ€‹greater than 1 will move percentage marks outside of the pie. However, the default text alignment for percentage labels (in the center) suggests that they are inside the pie. When they go beyond the cake, we will need to use a different alignment convention.

 import matplotlib.pyplot as plt import numpy as np np.random.seed(123456) import pandas as pd def align_labels(labels): for text in labels: x, y = text.get_position() h_align = 'left' if x > 0 else 'right' v_align = 'bottom' if y > 0 else 'top' text.set(ha=h_align, va=v_align) df = pd.DataFrame(3 * np.random.rand(4, 4), index=['a', 'b', 'c', 'd'], columns=['x', 'y','z','w']) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] fig, axes = plt.subplots(nrows=2, ncols=2) for ax, col in zip(axes.flat, df.columns): artists = ax.pie(df[col], autopct='%.2f', pctdistance=1.05, colors=colors) ax.set(ylabel='', title=col, aspect='equal') align_labels(artists[-1]) fig.legend(artists[0], df.index, loc='center') plt.show() 

enter image description here

+6
source

All Articles