Matplotlib Theta Ticks in Polar Plots

I have found that polar plots are often the most misunderstood chart type. While most Python developers stick to standard XY Cartesian coordinates, polar plots are essential when you are dealing with cyclical data like wind directions or seasonal sales cycles across the USA.

The most common hurdle I see beginners face is controlling the angular axis, specifically, how to set the “theta ticks” so the chart is actually readable for a professional audience.

In this tutorial, I will walk you through my personal process for customizing these ticks using Python’s Matplotlib library to ensure your polar visualizations look polished and professional.

Customize Theta Ticks in Python

When you create a default polar plot in Python, Matplotlib often guesses where the degree labels should go, but these defaults rarely align with specific business requirements.

If you are mapping out the frequency of hurricanes along the Atlantic coast or tracking the movement of a radar signal, you need precise control over the angular grid lines.

By manually setting theta ticks, you can change the degree intervals, update the labels to cardinal directions (N, S, E, W), or even use radians if your Python mathematical model requires it.

Method 1: Use the set_thetagrids() Function in Python Matplotlib

One of the easiest methods I use to manipulate the angular axis is the set_thetagrids() function. This is built directly into the Matplotlib polar axes class.

I find this method particularly useful when I have a specific set of angles in mind—for example, if I only want to highlight the 90-degree quadrants for a high-level summary of USA regional data.

1.1 Set Custom Degree Positions

When you call set_thetagrids(), you pass an array of angles where you want the grid lines to appear.

In this Python example, I will plot the average wind speeds for different compass headings in a coastal California city to show you how it works in a real-world scenario.

import matplotlib.pyplot as plt
import numpy as np

# Sample Python data: Wind speeds (mph) at different angles for a California pier
angles_degrees = [0, 45, 90, 135, 180, 225, 270, 315]
wind_speeds = [12, 15, 8, 22, 19, 14, 10, 11]

# Convert degrees to radians for Python Matplotlib plotting
angles_radians = np.deg2rad(angles_degrees)

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(8, 6))
ax.plot(angles_radians, wind_speeds, color='navy', linewidth=2, marker='o')

# Use set_thetagrids to specify exactly where the lines should be
# We will place ticks every 45 degrees
tick_locations = [0, 45, 90, 135, 180, 225, 270, 315]
ax.set_thetagrids(tick_locations)

ax.set_title("Average Wind Speed by Direction - California Coast", va='bottom', fontsize=14)
plt.show()

You can see the output in the screenshot below.

Matplotlib Theta Ticks in Polar Plots

1.2 Customize Theta Tick Labels with Text

While degrees are helpful, I often prefer to label the ticks with specific names to make the Python visualization easier for non-technical stakeholders in the USA to read.

You can pass a second list of strings to set_thetagrids() to replace the numeric degree values with text.

import matplotlib.pyplot as plt
import numpy as np

# Python data representing drone signal strength across a field in Texas
directions = [0, 90, 180, 270]
labels = ['North (Dallas)', 'East (Houston)', 'South (Brownsville)', 'West (El Paso)']
signal_strength = [85, 92, 78, 88]

angles_radians = np.deg2rad(directions)

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(8, 6))
ax.fill(angles_radians, signal_strength, color='tab:red', alpha=0.5)

# Applying custom labels to the theta ticks in Python
ax.set_thetagrids(directions, labels=labels)

ax.set_title("Drone Signal Coverage: Texas Regional Test", pad=20)
plt.show()

You can see the output in the screenshot below.

Theta Ticks in Polar Plots Matplotlib

Method 2: Use the ThetaLocator and ThetaFormatter for Advanced Control

When I am building a more complex Python application, I prefer using the Locator and Formatter classes. This approach is more “Pythonic” and offers much more flexibility for dynamic data.

This method separates the logic of where the ticks go from how the labels are formatted, which is a lifesaver when you are automating reports for different USA time zones or locations.

2.1 Implement the FixedLocator for Precise Placement

The FixedLocator is my “go-to” when I need the Python grid to remain static regardless of the data being zoomed or panned.

I often use this when displaying demographic shifts across a circular representation of a city center, like Central Park in New York.

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np

# Simulated Python data: Population density around a city center (e.g., NYC)
theta = np.linspace(0, 2*np.pi, 100)
density = 50 + 20 * np.sin(3 * theta)

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(8, 8))
ax.plot(theta, density, color='darkgreen', linestyle='--')

# Using Python's ticker module to locate ticks
# Setting ticks every 30 degrees
tick_points = np.arange(0, 360, 30)
ax.xaxis.set_major_locator(ticker.FixedLocator(np.deg2rad(tick_points)))

ax.set_title("Population Density Distribution (Radius: 5 Miles)", fontsize=15)
plt.show()

You can see the output in the screenshot below.

Theta Ticks in Polar Plots in Matplotlib

2.2 Use FuncFormatter for Dynamic Python Labeling

This is a trick I learned after years of trial and error. The FuncFormatter allows you to write a custom Python function to decide what each theta tick label should look like.

This is perfect if you want to add a “°” symbol or convert the degree value into something else entirely, like a specific timestamp or a compass bearing.

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np

# Python script to visualize solar intensity over a 24-hour cycle in Arizona
# 0 degrees = Midnight, 180 degrees = Noon
times = np.linspace(0, 2*np.pi, 24)
intensity = [0, 0, 0, 0, 0, 10, 30, 60, 85, 95, 100, 105, 100, 90, 70, 40, 15, 5, 0, 0, 0, 0, 0, 0]

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(9, 7))
ax.bar(times, intensity, width=0.2, color='orange', alpha=0.7)

# Custom Python function to format the labels as hours
def hour_formatter(x, pos):
    degree = np.rad2deg(x)
    hour = int(degree / 15)
    return f"{hour}:00"

ax.xaxis.set_major_formatter(ticker.FuncFormatter(hour_formatter))

ax.set_title("Solar Intensity Cycle - Phoenix, AZ", pad=30)
plt.show()

You can see the output in the screenshot below.

Matplotlib's Theta Ticks in Polar Plots

One thing I have noticed is that if you have too many theta ticks, your chart becomes cluttered and unreadable.

When I am designing dashboards for USA-based clients, I always try to keep it to 8 or 12 ticks maximum. This follows the standard “clock” or “compass” layout that most people are naturally accustomed to.

Also, remember that Matplotlib works in radians for the actual plotting but often uses degrees for the set_thetagrids function. Always double-check your unit conversions to avoid your data appearing in the wrong quadrant!

I hope you find this tutorial useful when you are building your next Python data visualization project. Customizing theta ticks might seem like a small detail, but it makes a massive difference in how professional your charts look.

You may also read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.