Dietrich Dietrich - 1 month ago 13
Python Question

How to draw a filled arc in matplotlib

In matplotlib, I would like draw an filled arc which looks like this:

Filled Arc Example

The following code results in an unfilled line arc:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

fg, ax = plt.subplots(1, 1)

pac = mpatches.Arc([0, -2.5], 5, 5, angle=0, theta1=45, theta2=135)
ax.add_patch(pac)

ax.axis([-2, 2, -2, 2])
ax.set_aspect("equal")
fg.canvas.draw()


The documentation says that filled arcs are not possible.
What would be the best way to draw one?

Answer

@jeanrjc's solution almost gets you there, but it adds a completely unnecessary white triangle, which will hide other objects as well (see figure below, version 1).

This is a simpler approach, which only adds a polygon of the arc:

Basically we create a series of points (points) along the edge of the circle (from theta1 to theta2). This is already enough, as we can set the close flag in the Polygon constructor which will add the line from the last to the first point (creating a closed arc).

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

def arc_patch(center, radius, theta1, theta2, ax=None, resolution=50, **kwargs):
    # make sure ax is not empty
    if ax is None:
        ax = plt.gca()
    # generate the points
    theta = np.linspace(np.radians(theta1), np.radians(theta2), resolution)
    points = np.vstack((radius*np.cos(theta) + center[0], 
                        radius*np.sin(theta) + center[1]))
    # build the polygon and add it to the axes
    poly = mpatches.Polygon(points.T, closed=True, **kwargs)
    ax.add_patch(poly)
    return poly

And then we apply it:

fig, ax = plt.subplots(1,2)

# @jeanrjc solution, which might hide other objects in your plot
ax[0].plot([-1,1],[1,-1], 'r', zorder = -10)
filled_arc((0.,0.3), 1, 90, 180, ax[0], 'blue')
ax[0].set_title('version 1')

# simpler approach, which really is just the arc
ax[1].plot([-1,1],[1,-1], 'r', zorder = -10)
arc_patch((0.,0.3), 1, 90, 180, ax=ax[1], fill=True, color='blue')
ax[1].set_title('version 2')

# axis settings
for a in ax:
    a.set_aspect('equal')
    a.set_xlim(-1.5, 1.5)
    a.set_ylim(-1.5, 1.5)

plt.show()

Result (version 2):

enter image description here