
It is possible. We can start with a normal pie chart . Then we will need to get the images into the plot. This is done using plt.imread and using matplotlib.offsetbox.OffsetImage . We need to find good coordinates and zoom levels to place the image so that it completely overlaps with the corresponding pie wedge. Then the wedge path of the pie is used as the path of the image clip , so that only a part remains inside the wedge. Setting the zorder of an unfilled wedge to a large number ensures that borders are placed on top of the image. Thus, the wedges seem to be filled with an image.
import matplotlib.pyplot as plt from matplotlib.patches import PathPatch from matplotlib.offsetbox import OffsetImage, AnnotationBbox total = [5,7,4] labels = ["Raspberries", "Blueberries", "Blackberries"] plt.title('Berries') plt.gca().axis("equal") wedges, texts = plt.pie(total, startangle=90, labels=labels, wedgeprops = { 'linewidth': 2, "edgecolor" :"k","fill":False, }) def img_to_pie( fn, wedge, xy, zoom=1, ax = None): if ax==None: ax=plt.gca() im = plt.imread(fn, format='png') path = wedge.get_path() patch = PathPatch(path, facecolor='none') ax.add_patch(patch) imagebox = OffsetImage(im, zoom=zoom, clip_path=patch, zorder=-10) ab = AnnotationBbox(imagebox, xy, xycoords='data', pad=0, frameon=False) ax.add_artist(ab) positions = [(-1,0.3),(0,-0.5),(0.5,0.5)] zooms = [0.4,0.4,0.4] for i in range(3): fn = "data/{}.png".format(labels[i].lower()) img_to_pie(fn, wedges[i], xy=positions[i], zoom=zooms[i] ) wedges[i].set_zorder(10) plt.show()
source share