I am trying to create a polar plot with a log scale on the radial axis but I keep getting an error. Some example code and the error are below. It seems to work fine in Cartesian coordinates, does anyone know what's happening??
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')
# carthesia
#ax.set_yscale('log')
# Plot data
#ax.pcolormesh(theta, r, r)
plt.gca().invert_yaxis()
ax.contourf(theta, r, r)
ax.set_ylim((0.0, 0.5))
plt.show()
Exception in Tkinter callback:
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1413, in __call__
return self.func(*args)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 236, in resize
self.show()
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 239, in draw
FigureCanvasAgg.draw(self)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_agg.py", line 421, in draw
self.figure.draw(self.renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/figure.py", line 898, in draw
func(*args)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 1997, in draw
a.draw(renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 1045, in draw
tick.draw(renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 239, in draw
self.label1.draw(renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/text.py", line 591, in draw
ismath=ismath)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_agg.py", line 156, in draw_text
return self.draw_mathtext(gc, x, y, s, prop, angle)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_agg.py", line 145, in draw_mathtext
x = int(x) + ox
ValueError: cannot convert float NaN to integer
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()
Set rscale
after set_ylim()
, like theta answered in the comments above.
来源:https://stackoverflow.com/questions/14919407/how-to-use-log-scale-on-polar-axis-in-matplotlib