Matplotlib polar plots let you control the angular (theta) tick positions, labels, and formatting directly through the set_xticks(), set_xticklabels(), and tick_params() methods on the polar Axes object. You set positions in radians (or degrees if you convert), supply custom label strings, and adjust font size, color, padding, and rotation using the same tick formatting options as Cartesian plots. This article explains the exact commands, common pitfalls, and formatting tricks so you can make polar charts that look exactly how you want.
Formula
The conversion between degrees and radians is the core math behind theta tick placement:
radians = degrees × (π / 180)
Where:
- degrees – the angle you want the tick to appear at, measured counterclockwise from the positive x-axis (0° is at 3 o’clock).
- radians – the unit Matplotlib actually uses internally for all angular values in polar plots.
Matplotlib’s polar axes expect theta values in radians. If you pass degrees directly, your ticks will be wildly misplaced (e.g., 90° will be interpreted as 90 radians ≈ 5156°, which wraps around many times). Always convert using np.deg2rad() or multiply by np.pi/180.
Worked Example
Using the default values from the calculator above – theta positions at 0°, 90°, 180°, and 270° – here’s the conversion:
- 0° → 0 × (π/180) = 0 radians
- 90° → 90 × (π/180) = π/2 ≈ 1.5708 radians
- 180° → 180 × (π/180) = π ≈ 3.1416 radians
- 270° → 270 × (π/180) = 3π/2 ≈ 4.7124 radians
So the tick positions in radians are [0, 1.5708, 3.1416, 4.7124]. The calculator’s first output shows exactly these values rounded to 2 decimal places: 0.00, 1.57, 3.14, 4.71. The second output just echoes the degrees you entered.
Setting Theta Tick Positions
To set tick positions on a polar plot, you call set_xticks() on the polar Axes object. For example:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
ax.set_xticks(np.deg2rad([0, 45, 90, 135, 180, 225, 270, 315]))
plt.show()
This places ticks every 45°. If you omit set_xticks(), Matplotlib auto-selects positions (usually 8 ticks starting at 0°). You can also use ax.set_xticks() with a list of radians directly – just remember to convert.
Customizing Tick Labels
By default, labels show the radian value (0, Ï€/2, Ï€, …). To change them to degrees or custom text, use set_xticklabels():
ax.set_xticks(np.deg2rad([0, 90, 180, 270]))
ax.set_xticklabels(['0°', '90°', '180°', '270°'])
You must pass exactly the same number of labels as tick positions. If you want degree symbols without the numeric value, just pass strings like ['E', 'N', 'W', 'S'] for a compass rose. For dynamic formatting, you can use a list comprehension:
ticks = np.deg2rad([0, 30, 60, 90])
ax.set_xticks(ticks)
ax.set_xticklabels([f'{int(np.rad2deg(t))}°' for t in ticks])
Formatting Tick Appearance
Use tick_params() to control size, color, padding, and label rotation:
ax.tick_params(axis='x', labelsize=12, labelcolor='red', pad=15, length=6, width=2)
- labelsize – font size of the theta tick labels
- labelcolor – color of the text
- pad – distance between the tick mark and the label (in points)
- length and width – size of the tick mark itself
- labelrotation – rotates the label text; useful if ticks are close together
For the radial (r) axis, use axis='y' instead. You can also hide theta ticks entirely with ax.set_xticks([]).
Common Mistakes and Misconceptions
The most frequent error is forgetting to convert degrees to radians. Another is mismatched label counts – if you set 8 tick positions but only pass 4 labels, Matplotlib will raise an error. A subtler issue: set_xticklabels() without first calling set_xticks() may not work as expected if the auto-ticks change. Always set positions first.
Also, the zero angle and direction are configurable. By default, 0° is at 3 o’clock and angles increase counterclockwise. If you want 0° at the top (like a compass), use ax.set_theta_zero_location('N'). To reverse the direction (clockwise), use ax.set_theta_direction(-1). These change the meaning of your tick positions, so adjust accordingly.
Comparison with Cartesian Ticks
Polar theta ticks behave like x-axis ticks on a Cartesian plot – both use set_xticks() and set_xticklabels(). However, there are key differences:
- Polar ticks are placed around a circle, so their positions are angular, not linear.
- Labels are not automatically rotated to align with the radius – they stay horizontal by default, which can look cluttered at some angles.
- The
padparameter moves labels radially outward, not in a fixed direction. - There is no gridline option for theta ticks beyond
grid()– the gridlines are radial lines from the center.
For most formatting tasks, the same tick_params() keywords work, but you’ll often need labelrotation to keep text readable.
Alternatives and Advanced Options
If you need more control than set_xticklabels() offers, you can use a FuncFormatter from matplotlib.ticker to dynamically generate labels based on radian values:
from matplotlib.ticker import FuncFormatter
def rad_to_deg(x, pos):
return f'{int(np.rad2deg(x))}°'
ax.xaxis.set_major_formatter(FuncFormatter(rad_to_deg))
This avoids manual label lists and automatically updates if you change tick positions. For even more customization, you can directly manipulate the ax.xaxis object’s tick labels after drawing, but that’s rarely needed. If you’re working with multiple subplots, remember that each polar Axes has its own theta tick settings – you must apply them per-axes.
Frequently Asked Questions
How do I show theta ticks in degrees instead of radians?
Convert your degree positions to radians when setting ticks, then pass degree-formatted strings to set_xticklabels(). For example: ax.set_xticks(np.deg2rad([0, 90, 180, 270])) followed by ax.set_xticklabels(['0°', '90°', '180°', '270°']).
Why are my theta tick labels overlapping?
This usually happens when you have many ticks or long labels. Increase the pad value in tick_params(), reduce the number of ticks, or rotate labels using labelrotation. For example, ax.tick_params(axis='x', pad=20, labelrotation=45).
Can I hide only the theta tick labels but keep the gridlines?
Yes. Set the tick labels to empty strings: ax.set_xticklabels([''] * len(ax.get_xticks())). The gridlines remain because they are tied to the tick positions, not the labels. Alternatively, use ax.set_xticks(positions) and ax.set_xticklabels([]).
How do I set tick positions every 30 degrees?
Use np.arange(0, 360, 30) for degrees, convert to radians with np.deg2rad(), and pass to set_xticks(). Then create labels for each position: ax.set_xticklabels([f'{d}°' for d in range(0, 360, 30)]).
What if I want the first tick at the top instead of the right?
Set the zero location before setting ticks: ax.set_theta_zero_location('N') puts 0° at the top. Then your tick positions are still measured from that new zero point. You may also need ax.set_theta_direction(-1) for clockwise increase if that matches your data.
Why does set_xticklabels() not work unless I call set_xticks() first?
Because set_xticklabels() operates on the current tick positions. If you haven’t explicitly set them, Matplotlib uses auto-generated positions that may be different from what you expect. Always call set_xticks() with your desired positions immediately before setting labels.
Related
Formula used
in theta_deg | Theta tick positions (degrees) | deg | 0, 90, 180, 270 | 0 | 360 in label_style | Label style (0=default, 1=degree symbols) | - | 0 | 0 | 1 out tick_rad | Tick positions (radians) | rad | theta_deg * (pi / 180) | 2 out tick_deg | Tick positions (degrees) | deg | theta_deg | 0
Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Motorola Phone Recovery: How to Recover Data
- Poco X3 GT Dimensity 1100 67W Fast Charging Launched?5.00 min/km
- Flash Converter: What It Is & How to Use It
- Choosing a Pipe Flow Meter for Swirling Flow
- Convert 2D Videos to Oculus Rift VR: How-To
- DRAM Light on Motherboard: Meaning & Fixes5.00 min/km