How to use log scale on polar axis in matplotlib

强颜欢笑 提交于 2019-12-05 18:23:15
Craig Finch

This appears to be a bug in matplotlib. You should not have to call the set_rlim (or set_ylim) method before set_rscale (or set_yscale). In addition, you must call set_rlim or set_ylim with the 0 or 0.0 as the lower limit. Other values for the lower limit will also result in a crash. The problem occurs with other backends as well (I have confirmed the issue for the gtkagg and pdf backends).

I filed a bug report for this issue, which can be found here. If this issue is affecting you, please go to the bug report page and leave a comment to let the matplotlib developers know that this issue is important to users.

There are more problems with the current matplotlib and log-polar plots.

For example, try to add a small value to the radius in the matplotlib example for polar plots, and then use set_rlim(0) and set_rscale('log') to plot it (as has been suggested in the comments here). All values below 0.1 get some special treatment. This affects the ticks on the r axis (note the completely misplaced 10e-2 and 10e-3) as well as the plotted data:

The behavior seems to be undocumented. I ended up doing the log-transform manually (third plot in the series above). For others coming across this thread, here is my code:

import numpy as np
import matplotlib.pyplot as plt

def scatter_polar_mpl(ax, theta, r):
    ax.scatter(theta, r)
    ax.set_rlim(0)
    ax.set_title('polar matplotlib')

def scatter_logpolar_mpl(ax, theta, r):
    ax.scatter(theta, r)
    ax.set_rlim(0)
    ax.set_rscale('log')
    ax.set_title('log-polar matplotlib')

def scatter_logpolar(ax, theta, r_, bullseye=0.3, **kwargs):
    min10 = np.log10(np.min(r_))
    max10 = np.log10(np.max(r_))
    r = np.log10(r_) - min10 + bullseye
    ax.scatter(theta, r, **kwargs)
    l = np.arange(np.floor(min10), max10)
    ax.set_rticks(l - min10 + bullseye) 
    ax.set_yticklabels(["1e%d" % x for x in l])
    ax.set_rlim(0, max10 - min10 + bullseye)
    ax.set_title('log-polar manual')
    return ax

r = np.arange(0, 3.0, 0.01) + 0.001

theta = 2 * np.pi * r

ax = plt.subplots(1, 3, subplot_kw=dict(polar=True))[1].flatten()
scatter_polar_mpl(ax[0], theta, r)
scatter_logpolar_mpl(ax[1], theta, r)
scatter_logpolar(ax[2], theta, r)

plt.show()

When I take out the comment in the line that sets up the plot window it runs for me.

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

bazbins = np.linspace(0, 2*np.pi, 360)
fbins = np.logspace(np.log10(0.05), np.log10(0.5), 101)
theta, r = np.meshgrid(bazbins, fbins) 

# Set up plot window
fig, ax = plt.subplots(figsize=(12,9), subplot_kw=dict(projection='polar'))

# polar
ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_rscale('log')

plt.gca().invert_yaxis()
ax.contourf(theta, r, r)
ax.set_ylim((0.0, 0.5))
plt.show() 
Dave

Set rscale after set_ylim(), like theta answered in the comments above.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!