Search code examples
pythonmatplotlibpie-chart

Only draw certain dividing lines between pie chart wedges


I would like to only draw certain dividing lines between wedges on a piechart.

This is what my chart looks like currently:
Current Chart

And this is what I would like it to look like:
Target Chart


While researching, I found that I could either add dividing lines using the wedgeprops attribute or after the chart is drawn like so:

wedges = plt.pie(sizes, labels=labels, colors=colours, autopct='%1.1f%%')
    for wedge in wedges[0]:
        wedge.set_lw(0.5)
        wedge.set_edgecolor("black")

However, from what I can see a wedge's line width property applies to the whole way around the wedge and I can't modify a single edge.

I found that by using patches you can draw just an outline circle for a chart like this:

circle = matplotlib.patches.Circle(center, radius, fill=False, edgecolor="k", linewidth=2)
ax.add_patch(circle)

But looking at the wiki, I can't see a patch for a single line. I did see matplotlib.lines.Line2D, but am unsure how to use it correctly in this context.

This is my full code. I am trying to not draw a dividing line between the "allocated" (orangered) and "padded") (salmon) sections.

def graph_memory_layout(memory_layout):
    # Format: F(ree)/A(llocated)[number of bytes]P(adding)[number of bytes] [space] [next entry]

    # Extract infomation
    layout = memory_layout.split()
    colours = []
    sizes=[]

    for memory in layout:
        first_char = memory[0]
        if (first_char == 'A'):
            allocated_bytes = 0
            padded_bytes = 0
            padded_flag = None

            for i, char in enumerate(memory[1:]):
                if char == 'P':
                    padded_flag = i + 1

            allocated_bytes = int(memory[1:padded_flag])
            padded_bytes = int(memory[padded_flag + 1:])

            payload_bytes = allocated_bytes - padded_bytes
            sizes.append(payload_bytes)
            colours.append(ALLOCATED_COLOUR)

            if padded_bytes is not 0:
                sizes.append(padded_bytes)
                colours.append(PADDED_COLOUR)
                # Perhaps I could track that these wedges shouldn't have a dividing line and use that infomation later somehow?
            
        elif (first_char == 'F'):
            sizes.append(memory[1:])
            colours.append(FREE_COLOUR)

    # Create pie chart 
    wedges = plt.pie(sizes, colors=colours)
    for wedge in wedges[0]:
        wedge.set_lw(0.5)
        wedge.set_edgecolor("black")

    plt.axis("equal")
    plt.title("Memory Layout")

     # Draw the chart
    plt.show()

Solution

  • You were on the right track. You need to outline the lower sector and draw a contour circle with the radius of the pie chart.

    import matplotlib.pyplot as plt
    import matplotlib.patches
    
    
    if __name__ == '__main__':
    
        data = [25.0, 25.0, 50.0]
    
        fig, ax = plt.subplots()
        wedges, _ = ax.pie(data)
    
        wedges[-1].set_linewidth(0.5)
        wedges[-1].set_edgecolor('k')
    
        center = wedges[0].center
        r = wedges[0].r
        circle = matplotlib.patches.Circle(center, r, fill=False, edgecolor="k", linewidth=0.5)
        ax.add_patch(circle)
    
        plt.show()