Drawing Shapes (Patches)

Patches are filled geometric shapes — rectangles, circles, polygons, and arrows — that you place directly on an axes to highlight regions, draw diagrams, or annotate your data with custom graphics.

Learn Drawing Shapes (Patches) in our free Matplotlib course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Matplotlib course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll add shapes with ax.add_patch() , control fill and outline with facecolor / edgecolor / alpha , draw arrows, and batch many shapes with a PatchCollection .

Patches live in the matplotlib.patches module. Build a shape, then call ax.add_patch() to place it. A Rectangle takes its bottom-left corner plus a width and height; a Circle takes a center and a radius. Patches do not auto-scale the view, so set the limits yourself.

What you'll see: a sky-blue rectangle with a navy outline on the left and a salmon circle with a dark-red outline on the right, both correctly proportioned because the aspect ratio is locked.

A Polygon takes an array of corner points, and a FancyArrow draws an arrow from a base point along a direction. A translucent Rectangle behind your data (low alpha ) is a clean way to shade a region of interest without hiding the line.

Calling add_patch hundreds of times is slow. A PatchCollection bundles a list of shapes into one artist you add with ax.add_collection() , and you can color them all at once — even map a data array through a colormap.

What you'll see: forty translucent circles scattered across the plot, each tinted along a viridis colormap by its radius, with a colorbar showing how size maps to color — all drawn in one efficient collection.

Replace each ___ to draw a green square on the axes.

Patches do not expand the view. ✅ Set ax.set_xlim() / set_ylim() (or call ax.autoscale_view() ) so the shape is inside the visible area.

The axes have unequal unit sizes. ✅ Call ax.set_aspect('equal') .

add_patch takes one patch. ✅ For many shapes, wrap them in PatchCollection and use ax.add_collection() .

Use a Rectangle for the housing and three Circles for the lights to draw a traffic light.

Lesson complete — you can draw on your plots!

You added rectangles, circles, polygons, and arrows, controlled fill and outline with facecolor, edgecolor, and alpha, shaded a region, and batched many shapes with a PatchCollection.

🚀 Up next: Interactive Event Handling — respond to clicks, key presses, and mouse motion in a live figure window.

Practice quiz

What is a patch in Matplotlib?

  • A bug fix
  • A filled 2-D shape like Rectangle or Circle
  • A type of colormap
  • A legend entry

Answer: A filled 2-D shape like Rectangle or Circle. A patch is a filled geometric shape from matplotlib.patches, such as Rectangle or Circle.

Which call places a single shape onto an axes?

  • ax.draw_shape()
  • ax.patch()
  • ax.shape()
  • ax.add_patch()

Answer: ax.add_patch(). ax.add_patch(shape) adds one patch to the axes.

What arguments does Rectangle take?

  • Its bottom-left corner plus a width and height
  • Two opposite corners
  • A center and radius
  • Four separate corner points

Answer: Its bottom-left corner plus a width and height. Rectangle((x, y), width, height) is defined by its bottom-left corner, width, and height.

What arguments does Circle take?

  • Three points on the circle
  • A bounding box
  • A center and a radius
  • A start and end angle

Answer: A center and a radius. Circle((cx, cy), r) is defined by its center and radius.

Why might a shape not appear after add_patch?

  • The color was wrong
  • Patches do not auto-scale the view, so set the limits
  • You must call it twice
  • Patches need a legend

Answer: Patches do not auto-scale the view, so set the limits. Patches do not expand the view; set ax.set_xlim()/set_ylim() so the shape is visible.

Why does a Circle sometimes look like an oval?

  • The radius is negative
  • alpha is too low
  • The figure is too small
  • The axes have unequal unit sizes

Answer: The axes have unequal unit sizes. Different pixel sizes per data unit squash a circle; ax.set_aspect('equal') fixes it.

What does facecolor control?

  • The interior fill of the shape
  • The axis labels
  • The outline only
  • The shadow

Answer: The interior fill of the shape. facecolor fills the interior, while edgecolor draws the outline.

How do you make a shape hollow so only its outline shows?

  • alpha=0
  • Set fill=None and no edge
  • facecolor='none'
  • Remove the patch

Answer: facecolor='none'. facecolor='none' leaves the interior empty so only the edge shows.

How do you draw many shapes efficiently and color them together?

  • Call add_patch in a loop only
  • Use plt.scatter
  • Plot each as a line
  • Wrap them in a PatchCollection and add_collection()

Answer: Wrap them in a PatchCollection and add_collection(). A PatchCollection bundles many shapes into one artist added with ax.add_collection().

What does set_aspect('equal') ensure?

  • The figure is square inches
  • One data unit takes the same pixels on both axes
  • The axes are logarithmic
  • The patch is filled

Answer: One data unit takes the same pixels on both axes. set_aspect('equal') makes one data unit equal pixels on both axes, so circles look round.