How to draw a polygon in Python
Learn how to draw a polygon in Python with various methods. Discover tips, real-world applications, and how to debug common errors.
.png)
Python lets you draw polygons, a fundamental skill for developers who work with computer graphics and data visualization. Its libraries offer powerful tools to create complex shapes with simple code.
In this article, we'll explore several techniques to draw polygons. You'll find practical tips, see real-world applications, and get debugging advice to help you master the creation of any shape.
Using the turtle module
import turtle
t = turtle.Turtle()
sides = 5
length = 100
for _ in range(sides):
t.forward(length)
t.right(360 / sides)
turtle.done()--OUTPUT--A pentagon drawn in a turtle graphics window.
The turtle module offers an intuitive way to draw by guiding a virtual pen around a canvas. This code uses a loop that iterates based on the number of sides you want the polygon to have. It's a simple yet powerful approach for creating geometric figures.
Inside the loop, t.forward() draws each side to a specified length. The crucial part is t.right(360 / sides), which calculates the correct external angle for a regular polygon. This ensures the turtle turns just the right amount at each corner to form a closed shape once all sides are drawn.
Basic polygon drawing techniques
Beyond the turtle module's simplicity, Python provides more specialized libraries like matplotlib, pygame, and PIL for drawing polygons in various applications.
Drawing polygons with matplotlib
import matplotlib.pyplot as plt
import numpy as np
angles = np.linspace(0, 2*np.pi, 6, endpoint=False)
x, y = np.cos(angles), np.sin(angles)
plt.plot(np.append(x, x[0]), np.append(y, y[0]), 'b-')
plt.axis('equal')
plt.show()--OUTPUT--A blue hexagon displayed in a matplotlib figure window.
For more complex visualizations, matplotlib plots polygons by connecting a series of coordinates. This approach uses numpy to generate the vertices of a regular polygon. The np.linspace function creates evenly spaced angles, and then trigonometric functions like np.cos and np.sin convert these angles into x and y coordinates.
The key step is in the plt.plot call. By appending the first coordinate to the end of the arrays with np.append, you instruct matplotlib to draw the final line that closes the shape. Using plt.axis('equal') keeps the proportions correct, so your polygon appears regular and not distorted.
Using pygame to create polygons
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
polygon_points = [(200, 100), (300, 200), (200, 300), (100, 200)]
pygame.draw.polygon(screen, (0, 255, 0), polygon_points, 2)
pygame.display.flip()
pygame.time.wait(3000) # Display for 3 seconds--OUTPUT--A green rhombus outline displayed in a pygame window for 3 seconds.
When you're building games or interactive apps, pygame is a great choice. You define a polygon by creating a list of (x, y) coordinates for its vertices. The pygame.draw.polygon() function then takes this list and renders the shape onto a display surface.
- The function’s arguments control the output: the
screento draw on, the color as an RGB tuple, and the list of points. - The final argument,
2, sets the line thickness. This draws an outline—if you omit it, the polygon will be filled in.
Finally, pygame.display.flip() updates the entire screen so your new shape becomes visible.
Creating polygons with the PIL library
from PIL import Image, ImageDraw
img = Image.new('RGB', (300, 300), color = (255, 255, 255))
draw = ImageDraw.Draw(img)
points = [(150, 50), (250, 150), (150, 250), (50, 150)]
draw.polygon(points, outline='black', fill='red')
img.show()--OUTPUT--A red rhombus with black outline displayed in an image viewer.
The Python Imaging Library (PIL) is ideal for image manipulation. You begin by creating a blank canvas with Image.new(). From there, you create a drawing context using ImageDraw.Draw(), which allows you to add shapes to your image.
- Similar to
pygame, you define the polygon's vertices as a list of(x, y)coordinate tuples. - The
draw.polygon()function renders the shape, letting you specify separate colors for thefillandoutline.
Finally, calling img.show() opens the completed image in your system's default viewer.
Advanced polygon techniques
Building on these foundational methods, you can now create precise regular polygons, extend your shapes into three dimensions, and even animate their movements.
Creating regular polygons with shapely
from shapely.geometry import Point
import matplotlib.pyplot as plt
center = Point(0, 0)
polygon = center.buffer(1, cap_style=3, resolution=5)
x, y = polygon.exterior.xy
plt.plot(x, y)
plt.axis('equal')
plt.show()--OUTPUT--A regular pentagon created with geometric operations displayed in a matplotlib figure.
The shapely library approaches drawing from a geometric perspective, letting you create shapes through operations. You start by defining a Point object, then use the buffer() method to generate a polygon around it.
- The first argument in
buffer()sets the distance from the center to each vertex. - The
resolutionparameter is what defines the number of sides—a value of5creates a pentagon.
Once the shape is created, you can extract its coordinates with polygon.exterior.xy for plotting.
Drawing 3D polygons with the mplot3d module
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
angles = np.linspace(0, 2*np.pi, 6, endpoint=False)
x, y = np.cos(angles), np.sin(angles)
ax.plot(np.append(x, x[0]), np.append(y, y[0]), np.zeros(7), 'r-')
plt.show()--OUTPUT--A 3D hexagon in the xy-plane displayed in a matplotlib 3D figure.
To move into three dimensions, you’ll use matplotlib’s mplot3d toolkit. The key is setting up a 3D plotting area by adding projection='3d' when you create the subplot. This tells matplotlib to prepare for 3D data.
- The
ax.plot()function now takes three arguments for coordinates: x, y, and z.
While the x and y coordinates define the shape's vertices on a flat plane, the z-coordinates give it depth. In this example, np.zeros(7) places the entire polygon on the xy-plane, creating a 2D shape within a 3D space.
Creating animated polygons with matplotlib.animation
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
polygon, = ax.plot(np.cos(np.linspace(0, 2*np.pi, 6)), np.sin(np.linspace(0, 2*np.pi, 6)), 'r-')
ax.set_xlim(-1.5, 1.5); ax.set_ylim(-1.5, 1.5)
ani = FuncAnimation(fig, lambda i: polygon.set_data(np.cos(np.linspace(0, 2*np.pi, 6) + i/10), np.sin(np.linspace(0, 2*np.pi, 6) + i/10)), frames=60, interval=50)
plt.show()--OUTPUT--An animated rotating hexagon displayed in a matplotlib window.
You can animate your polygons using matplotlib’s animation tools. The magic happens with FuncAnimation, which repeatedly calls a function to update your plot, creating smooth motion. It’s like a digital flipbook for your data.
- At its core, a
lambdafunction is called for each frame. It usespolygon.set_data()to feed the plot new x and y coordinates. - The rotation effect comes from adding the frame number
ito the angle calculation, which shifts the polygon's position slightly with every update. - Parameters like
framesandintervalgive you direct control over the animation's total length and playback speed.
Move faster with Replit
Replit is an AI-powered development platform where all Python dependencies come pre-installed, so you can skip setup and start coding instantly. This allows you to move from learning individual techniques to building complete applications with Agent 4.
Instead of piecing everything together yourself, you can describe the app you want to build and have Agent create it:
- A tool that generates custom geometric patterns for graphic design assets.
- An interactive map utility that lets users draw and measure polygonal areas.
- A simple 2D game where players navigate through a maze of polygonal obstacles.
Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.
Common errors and challenges
Drawing polygons in Python can be tricky, but most errors are simple to fix once you know what to look for.
A common frustration with the turtle module is having the graphics window close the instant the script finishes drawing. This happens because the program has finished executing. To prevent this, you need to tell the script to wait.
- Add
turtle.done()at the end of your code. This function keeps the window open and responsive until you manually close it.
In pygame, your window might become unresponsive or close immediately after launching. This is because pygame applications require an active event loop to process inputs and keep the display updated.
- You must implement a loop that continuously checks for events, like a user clicking the close button. Without this event-handling loop, the program runs from top to bottom and then simply exits.
You might find your matplotlib polygon has a gap instead of being a closed shape. The plt.plot() function connects coordinates in the exact order you provide them, so if the last point isn't connected to the first, the shape remains open.
- To fix this, you must explicitly connect the last vertex back to the first. Simply append the first coordinate pair to the end of your list of vertices before plotting.
Fixing the turtle screen that closes immediately
When your turtle script finishes, the graphics window often closes instantly. This isn't a bug; it's the expected behavior once a program has completed its tasks, leaving you with only a fleeting glimpse. The following code demonstrates this common issue.
import turtle
t = turtle.Turtle()
sides = 5
length = 100
for _ in range(sides):
t.forward(length)
t.right(360 / sides)
# Window will close immediately
The script runs from top to bottom. After the for loop finishes drawing the shape, there's nothing left for the program to do, so it exits. The updated code below shows the simple fix.
import turtle
t = turtle.Turtle()
sides = 5
length = 100
for _ in range(sides):
t.forward(length)
t.right(360 / sides)
turtle.done() # Keeps the window open until manually closed
The fix is simple: call turtle.done() as the last line of your script. This function puts the turtle graphics into a waiting state, listening for user actions like closing the window. It’s a crucial final step that keeps your drawing on screen until you manually exit, preventing it from disappearing the moment the code finishes running.
Handling events in pygame polygon applications
A frequent issue in pygame is a window that freezes or won't close properly. This happens because the application isn't handling user inputs or system events, leaving it unresponsive. The code below demonstrates this common pitfall.
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
polygon_points = [(200, 100), (300, 200), (200, 300), (100, 200)]
pygame.draw.polygon(screen, (0, 255, 0), polygon_points, 2)
pygame.display.flip()
pygame.time.wait(3000) # Window may become unresponsive
The pygame.time.wait() function pauses the program but doesn't handle events like closing the window, making it unresponsive. The corrected code below shows how to properly manage the application's lifecycle and keep it interactive.
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
polygon_points = [(200, 100), (300, 200), (200, 300), (100, 200)]
pygame.draw.polygon(screen, (0, 255, 0), polygon_points, 2)
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
The fix replaces the unresponsive pygame.time.wait() with a proper event loop. This loop is the core of any interactive pygame application, as it constantly listens for user actions and keeps the window from freezing.
- The
while running:block keeps the program active. - Inside,
pygame.event.get()checks for events like closing the window. - If a
pygame.QUITevent is detected, the loop ends, andpygame.quit()closes the application cleanly.
Fixing unclosed polygons in matplotlib
When your matplotlib polygon appears with a missing side, it’s because the plot isn't a closed loop. The plt.plot() function connects vertices sequentially and won't automatically join the last point back to the first. The code below demonstrates this common pitfall.
import matplotlib.pyplot as plt
import numpy as np
angles = np.linspace(0, 2*np.pi, 6, endpoint=False)
x, y = np.cos(angles), np.sin(angles)
plt.plot(x, y, 'b-') # Polygon isn't closed
plt.axis('equal')
plt.show()
The x and y arrays define the hexagon's six vertices, but the plt.plot() call only draws the five segments connecting them, leaving the shape incomplete. The corrected code below demonstrates the simple fix.
import matplotlib.pyplot as plt
import numpy as np
angles = np.linspace(0, 2*np.pi, 6, endpoint=False)
x, y = np.cos(angles), np.sin(angles)
plt.plot(np.append(x, x[0]), np.append(y, y[0]), 'b-') # Connects back to first point
plt.axis('equal')
plt.show()
The fix is to append the starting coordinate to the end of your x and y arrays using np.append(x, x[0]) and np.append(y, y[0]). This gives the plt.plot() function the final point it needs to draw the line that completes the shape. You'll want to watch for this whenever you're plotting custom shapes from a list of vertices, as matplotlib won't close the loop for you automatically.
Real-world applications
Moving beyond the fundamentals, drawing polygons is essential for real-world tasks like creating architectural layouts and visualizing geographic data.
Creating a simple floor plan with PIL
The PIL library is well-suited for this, allowing you to draw and fill several polygons on one canvas to map out a simple floor plan.
from PIL import Image, ImageDraw
img = Image.new('RGB', (400, 300), 'white')
draw = ImageDraw.Draw(img)
draw.polygon([(50, 50), (200, 50), (200, 150), (50, 150)], outline='black', fill='lightgray')
draw.polygon([(210, 50), (350, 50), (350, 150), (210, 150)], outline='black', fill='lightblue')
draw.polygon([(50, 160), (150, 160), (150, 250), (50, 250)], outline='black', fill='lightgreen')
img.show()
This code demonstrates how to layer multiple shapes on a single image. It starts by creating a white canvas with Image.new(). Then, an ImageDraw.Draw() object gives you the tools to draw on that canvas.
- Each
draw.polygon()call adds a distinct rectangular shape defined by a list of(x, y)vertex coordinates. - You can customize each polygon's appearance using the
outlineandfillcolor arguments.
Finally, img.show() opens the image with all the drawn polygons rendered.
Visualizing geographic data with folium
With folium, you can draw polygons directly onto interactive maps, making it an excellent tool for visualizing geographic boundaries like city parks or specific districts.
import folium
m = folium.Map(location=[37.76, -122.45], zoom_start=12)
park_coords = [[37.77, -122.51], [37.77, -122.45], [37.76, -122.45], [37.76, -122.51]]
folium.Polygon(locations=park_coords, color='green', fill=True).add_to(m)
m.save('map.html')
This code generates an interactive map by first initializing a map object with folium.Map(), setting its center and zoom level. A list of latitude and longitude coordinates, park_coords, defines the vertices of the polygon you want to draw.
- The
folium.Polygon()function takes these points and renders the shape. - It's then layered onto the map using the
.add_to(m)method. - Finally,
m.save()exports the entire map as an HTML file, which you can open in any web browser.
Get started with Replit
Put your new skills to work with Replit Agent. Describe your goal, like “a tool that calculates the area of a user-drawn polygon” or “a script that generates a floor plan from coordinates.”
Replit Agent writes the code, tests for errors, and deploys the app for you. Start building with Replit.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.


.png)
