HansSnah
HansSnah

Reputation: 2250

matplotlib polar plot tick/axis label position

I have been looking for a way to reliably position the tick and axis labels in a plot in polar coordinates. Please take a look at the following example:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=[10, 5])
ax0 = fig.add_axes([0.05, 0.05, 0.4, 0.9], projection="polar")
ax1 = fig.add_axes([0.55, 0.05, 0.4, 0.9], projection="polar")

r0 = np.linspace(10, 12, 10)
theta0 = np.linspace(0, 0.1, 10)

ax0.quiver(theta0, r0, -0.1, 0.1)
ax1.quiver(theta0 + np.pi, r0, -0.1, 0.1)

ax0.set_thetamin(-2)
ax0.set_thetamax(10)

ax1.set_thetamin(178)
ax1.set_thetamax(190)

for ax in [ax0, ax1]:

    # Labels
    ax.set_xlabel("r")
    ax.set_ylabel(r"$\theta$", labelpad=10)

    # R range
    ax.set_rorigin(0)
    ax.set_rmin(9)
    ax.set_rmax(13)

plt.show()

which results in this figure:

polar plot You can clearly see that

(a) the tick label position on the radial axis switches from bottom to top between the plots and the tick labels for theta switch from right to left.

(b) the axis label positions are fixed. I'd want the axis labels to also move with the tick labels. i.e. in the left plot, "theta" should be on the right, and in the right plot "r" should be on top.

How do I control the axis/tick labels in a way, so that they are positioned correctly? This even gets worse for e.g. a 90 degree shift, because then the theta axis is actually vertical and the tick labels are then totally off.

Upvotes: 5

Views: 8555

Answers (2)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339230

I think the most important bit is to become clear about how the usual notions of left, right, bottom, top translate into the polar axes in matplotlib.

enter image description here

The angular axis is the "x"-axis. The radial axis is the "y"-axis. The "bottom" is the outer ring. The "top" is the inner ring. "Left" is the radial axis at the start of the angular axis, "right" is the end of it.

This then allows to set the tick locations as usual, e.g.

ax.tick_params(labelleft=True, labelright=False,
               labeltop=False, labelbottom=True)

for the case shown above.

The x and y labels (set_xlabel / set_ylabel) are not translated. Here left, right, top, bottom refer to the cartesian definition, just as with normal linear axes. This means that for certain positions, they cannot be used to label the axis, because they are just too far away. An alternative is to create a text at the desired position.

A complete example code:

import numpy as np
import matplotlib.pyplot as plt

fig, (ax0, ax1) = plt.subplots(ncols=2, figsize=(10,5), 
                               subplot_kw=dict(projection="polar"))

ax0.set(thetamin=180, thetamax=230)
ax1.set(thetamin=  0, thetamax= 50)

plt.setp([ax0, ax1], rorigin=0, rmin=5, rmax=10)

ax0.tick_params(labelleft=False, labelright=True,
                labeltop=True, labelbottom=False)

trans, _ , _ = ax1.get_xaxis_text1_transform(-10)
ax1.text(np.deg2rad(22.5), -0.18, "Theta Label", transform=trans, 
         rotation=22.5-90, ha="center", va="center")


plt.show()

enter image description here

Upvotes: 7

Jacob Fuchs
Jacob Fuchs

Reputation: 357

To answer question (b):

ax0.yaxis.set_label_position('right')
ax1.xaxis.set_label_position('top')

In addition, I modified the ax.set_ylabel(r"$\theta$", labelpad=15)

enter image description here

Upvotes: 1

Related Questions