DEV Community

Allen Yang
Allen Yang

Posted on

How to Draw Lines, Rectangles, and Shapes in PDF Using Python

Drawing Graphics in PDF Using Python

In everyday document processing, PDF has become the go-to format for distribution and archiving thanks to its cross-platform consistency. However, when generating PDFs, text content alone is often not enough—many scenarios require adding visual elements to the document, such as drawing dividers, highlighting rectangular areas, or adding decorative shapes. Whether you're dividing sections in a report or sketching prototype elements in a design draft, programmatic drawing is a fundamental and practical skill.

This article introduces how to draw common graphics in PDF documents using Python, including lines, rectangles, ellipses, and more complex custom paths.

Why Draw Graphics Programmatically

Drawing graphics in PDF through code offers several advantages over manual operations:

  • Precise Control — The coordinates, dimensions, colors, and transparency of graphics can be defined precisely through parameters, eliminating the deviations caused by manual dragging
  • Batch Generation — With loops and conditional logic, you can generate large volumes of documents containing graphical elements at once
  • Dynamic Content — Automatically adjust the position and style of graphics based on data sources, making it ideal for reports and templates

Environment Setup

This article uses the Spire.PDF library to create PDF documents and draw graphics. Install it as follows:

pip install Spire.PDF
Enter fullscreen mode Exit fullscreen mode

This library provides comprehensive PDF manipulation capabilities, including page management, graphics drawing, and text rendering.

Drawing Basic Shapes

Spire.PDF provides a series of drawing methods through the PdfCanvas object. All drawing operations are performed on the page's Canvas. The canvas uses a coordinate system with the origin at the bottom-left corner of the page, and the unit is points (1 point = 1/72 inch).

Drawing Lines

Drawing a line is the most basic graphics operation. Use the DrawLine() method by specifying the start and end coordinates.

from spire.pdf.common import *
from spire.pdf import *

# Create a PDF document
doc = PdfDocument()
page = doc.Pages.Add()

# Save the canvas state
state = page.Canvas.Save()

# Create a pen (black, line width 1 point)
pen = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)

# Draw a horizontal line from (50, 100) to (400, 100)
page.Canvas.DrawLine(pen, 50.0, 100.0, 400.0, 100.0)

# Draw a diagonal line from (50, 100) to (225, 300)
pen2 = PdfPen(PdfRGBColor(Color.get_Red()), 1.0)
page.Canvas.DrawLine(pen2, 50.0, 100.0, 225.0, 300.0)

# Restore the canvas state
page.Canvas.Restore(state)

# Save the document
doc.SaveToFile("DrawLines.pdf")
doc.Close()
Enter fullscreen mode Exit fullscreen mode

PdfPen is the core tool for drawing lines—it determines the color and width of the line. The first two parameters of DrawLine() are the start coordinates, and the last two are the end coordinates. It's a good practice to call Save() and Restore() around each drawing operation to avoid affecting previous drawing settings with subsequent operations.

Drawing Dashed Lines

In real-world development, dashed lines are often used to separate sections or mark boundaries. This can be achieved by setting the pen's DashStyle and DashPattern properties.

# Create a red pen with a line width of 3 points
pen = PdfPen(PdfRGBColor(Color.get_Red()), 3.0)

# Set the dash style
pen.DashStyle = PdfDashStyle.Dash
pen.DashPattern = [1, 4, 1]  # Dash pattern: 1pt solid, 4pt gap, 1pt solid

# Draw the dashed line
page.Canvas.DrawLine(pen, 50.0, 200.0, 400.0, 200.0)
Enter fullscreen mode Exit fullscreen mode

The PdfDashStyle enum provides predefined dash styles (Dash, Dot, DashDot, etc.), while DashPattern allows you to define a more precise custom dash pattern—the numbers in the array alternately represent the lengths of solid segments and gaps.

Drawing Rectangles

Rectangles are among the most commonly used shapes for document annotation. You can draw either a rectangular border or a filled rectangle.

# Draw a rectangular border
pen = PdfPen(PdfRGBColor(Color.get_Black()), 0.5)
# Parameters: pen, x, y, width, height
page.Canvas.DrawRectangle(pen, 100.0, 150.0, 200.0, 120.0)

# Draw a filled rectangle
pen2 = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)
brush = PdfSolidBrush(PdfRGBColor(Color.get_OrangeRed()))
rect = RectangleF(PointF(100.0, 300.0), SizeF(200.0, 120.0))
page.Canvas.DrawRectangle(pen2, brush, rect)
Enter fullscreen mode Exit fullscreen mode

DrawRectangle() has two common overloads: one draws only the border and accepts a pen along with position parameters; the other draws a fill as well and takes an additional PdfBrush object. PdfSolidBrush is the most commonly used fill brush, filling the interior of a shape with a single color.

Drawing Ellipses

Ellipses and circles are common in diagram annotations and can be drawn using the DrawEllipse() method.

# Draw an elliptical border (defined by a bounding rectangle)
pen = PdfPen(PdfRGBColor(Color.get_CadetBlue()), 1.0)
# The parameters define the bounding rectangle; the ellipse is drawn inside it
page.Canvas.DrawEllipse(pen, 220.0, 320.0, 100.0, 90.0)

# Draw a filled ellipse
brush = PdfSolidBrush(PdfRGBColor(Color.get_CadetBlue()))
page.Canvas.DrawEllipse(brush, 380.0, 325.0, 80.0, 80.0)

# The third and fourth parameters control the horizontal and vertical radii
# When both are equal, the ellipse becomes a perfect circle
page.Canvas.DrawEllipse(brush, 100.0, 450.0, 50.0, 50.0)  # This draws a perfect circle
Enter fullscreen mode Exit fullscreen mode

An ellipse is essentially defined by its bounding rectangle: the closer the rectangle is to a square, the closer the ellipse is to a perfect circle. This approach is conceptually similar to the way ellipses are drawn on an HTML Canvas.

Drawing Custom Paths

For complex shapes like stars or polygons, you can combine multiple line segments using the PdfPath object and then draw them all at once with the DrawPath() method.

import math

# Calculate the five vertices of a pentagon
points = [None] * 5
for i in range(5):
    x = float(math.cos(i * 2 * math.pi / 5))
    y = float(math.sin(i * 2 * math.pi / 5))
    points[i] = PointF(x, y)

# Create a path and add line segments
path = PdfPath()
path.AddLine(points[2], points[0])
path.AddLine(points[0], points[3])
path.AddLine(points[3], points[1])
path.AddLine(points[1], points[4])
path.AddLine(points[4], points[2])

# Draw the path outline
pen = PdfPen(PdfRGBColor(Color.get_DeepSkyBlue()), 0.02)
page.Canvas.ScaleTransform(50.0, 50.0)
page.Canvas.TranslateTransform(5.0, 5.0)
page.Canvas.DrawPath(pen, path)

# Draw the filled path
brush = PdfSolidBrush(PdfRGBColor(Color.get_DeepSkyBlue()))
page.Canvas.DrawPath(pen, brush, path)
Enter fullscreen mode Exit fullscreen mode

PdfPath supports building shapes segment by segment using methods like AddLine(), AddArc(), and AddCurve(). ScaleTransform() and TranslateTransform() are used to scale and translate the coordinate system, making it easy to draw the same shape at different positions.

Controlling Shape Transparency

Transparency control creates richer visual effects when shapes overlap. Use the SetTransparency() method to set the transparency level for subsequent drawing operations.

# Set transparency (range 0.0~1.0, where 0.0 is fully transparent and 1.0 is fully opaque)
page.Canvas.SetTransparency(0.5, 0.5)

# Shapes drawn after this will be rendered at 50% opacity
pen = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)
brush = PdfSolidBrush(PdfRGBColor(Color.get_Red()))
page.Canvas.DrawRectangle(pen, brush, RectangleF(PointF(200.0, 300.0), SizeF(200.0, 100.0)))

# Set a different transparency level
page.Canvas.SetTransparency(0.2, 0.2)
page.Canvas.DrawRectangle(pen, brush, RectangleF(PointF(300.0, 250.0), SizeF(200.0, 100.0)))
Enter fullscreen mode Exit fullscreen mode

Transparency is especially useful when working with multi-layered shapes, such as distinguishing different levels of annotations in a product design draft.

Complete Example: Drawing Multiple Shapes Together

The following code combines all the drawing operations introduced above into a single document, producing a comprehensive example that includes lines, rectangles, ellipses, and custom paths.

from spire.pdf.common import *
from spire.pdf import *
import math

# Create a document
doc = PdfDocument()
page = doc.Pages.Add()

# Save the canvas state
state = page.Canvas.Save()

# 1. Draw a line
pen = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)
page.Canvas.DrawLine(pen, 50.0, 50.0, 200.0, 50.0)

# 2. Draw a dashed line
pen_dash = PdfPen(PdfRGBColor(Color.get_Red()), 2.0)
pen_dash.DashStyle = PdfDashStyle.Dash
page.Canvas.DrawLine(pen_dash, 50.0, 80.0, 200.0, 80.0)

# 3. Draw a rectangular border
pen_rect = PdfPen(PdfRGBColor(Color.get_Blue()), 1.0)
page.Canvas.DrawRectangle(pen_rect, 50.0, 120.0, 150.0, 100.0)

# 4. Draw a filled rectangle
pen_fill = PdfPen(PdfRGBColor(Color.get_Black()), 0.5)
brush_fill = PdfSolidBrush(PdfRGBColor(Color.get_OrangeRed()))
page.Canvas.DrawRectangle(pen_fill, brush_fill, 
    RectangleF(PointF(50.0, 250.0), SizeF(150.0, 100.0)))

# 5. Draw an ellipse
brush_ellipse = PdfSolidBrush(PdfRGBColor(Color.get_CadetBlue()))
page.Canvas.DrawEllipse(brush_ellipse, 300.0, 120.0, 100.0, 80.0)

# 6. Draw a perfect circle
page.Canvas.DrawEllipse(brush_ellipse, 300.0, 250.0, 60.0, 60.0)

# Restore the canvas state
page.Canvas.Restore(state)

# Save
doc.SaveToFile("ShapesDemo.pdf")
doc.Close()
Enter fullscreen mode Exit fullscreen mode

Output preview:

Drawing Graphics in PDF Using Python

Conclusion

This article introduced the basic methods for drawing graphics in PDF documents using Python, covering common elements such as lines, dashed lines, rectangles, ellipses, and custom paths. In real-world development, these fundamental drawing capabilities can be combined and applied to many scenarios—for instance, drawing table borders in reports, adding annotation frames in design drafts, or creating decorative lines in certificate templates.

Once you've mastered these basic graphics techniques, you can explore more advanced drawing capabilities such as gradient fills, shape transformations, and layer management to meet more complex document processing needs.

Top comments (0)