HotDogCannon
HotDogCannon

Reputation: 2386

How to format a polar contour plot in matplotlib

I have some sample code to make a polar contour plot:

import numpy as np
import matplotlib.pyplot as plt

azimuths = np.radians(np.linspace(0, 180, 90))
zeniths = np.arange(50, 5050, 50)

r, theta = np.meshgrid(zeniths, azimuths)
values = 90.0+5.0*np.random.random((len(azimuths), len(zeniths)))

fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
ax.set_theta_zero_location("W")
pp = plt.contourf(theta, r, values, label='tmp')
cbar = plt.colorbar(pp, orientation='vertical')
cbar.ax.set_ylabel('scale label')
plt.show()

which gives me something like:

enter image description here

...but I would like something more like this:

enter image description here

...with space in the middle, and only showing 0 to 180 degrees. Does anyone know of a convenient way to do this?

Upvotes: 2

Views: 3471

Answers (1)

wflynny
wflynny

Reputation: 18521

I'm not sure how convenient this is, but here's a hackable solution (taken from here):

import numpy as np

import mpl_toolkits.axisartist.floating_axes as floating_axes
from matplotlib.projections import PolarAxes
from mpl_toolkits.axisartist.grid_finder import FixedLocator, MaxNLocator, \
             DictFormatter
import matplotlib.pyplot as plt

tr = PolarAxes.PolarTransform()

degree_ticks = lambda d: (d*np.pi/180, "%d$^\\circ$"%(360-d))
angle_ticks = map(degree_ticks, np.linspace(180, 360, 5))
grid_locator1 = FixedLocator([v for v, s in angle_ticks])
tick_formatter1 = DictFormatter(dict(angle_ticks))
tick_formatter2 = DictFormatter(dict(zip(np.linspace(1000, 6000, 6),
                                         map(str, np.linspace(0, 5000, 6)))))

grid_locator2 = MaxNLocator(5)

gh = floating_axes.GridHelperCurveLinear(tr,
                                         extremes=(2*np.pi, np.pi, 1000, 6000),
                                         grid_locator1=grid_locator1,
                                         grid_locator2=grid_locator2,
                                         tick_formatter1=tick_formatter1,
                                         tick_formatter2=tick_formatter2)

fig = plt.figure()
ax = floating_axes.FloatingSubplot(fig, 111, grid_helper=gh)
fig.add_subplot(ax)

azimuths = np.radians(np.linspace(180, 360, 90)) # added 180 degrees
zeniths = np.arange(1050, 6050, 50) # added 1000

r, theta = np.meshgrid(zeniths, azimuths)
values = 90.0+5.0*np.random.random((len(azimuths), len(zeniths)))

aux_ax = ax.get_aux_axes(tr)
aux_ax.patch = ax.patch
ax.patch.zorder = 0.9

aux_ax.contourf(theta, r, values) # use aux_ax instead of ax

plt.show()

Note that (in order to get the space near the origin), you'll need to shift all your data points by 1000 in the radius direction and by pi in the theta direction (to get the lower hemisphere). This yields:

enter image description here

Upvotes: 1

Related Questions