Как использовать логарифмическую шкалу на полярной оси в matplotlib

Я пытаюсь создать полярный график с логарифмической шкалой по радиальной оси, но постоянно получаю сообщение об ошибке. Некоторые примеры кода и ошибки приведены ниже. Кажется, в декартовых координатах все работает нормально, кто-нибудь знает, что происходит ??

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()

Исключение в обратном вызове Tkinter:

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

person Dave    schedule 17.02.2013    source источник


Ответы (4)


Похоже, это ошибка в matplotlib. Вам не нужно вызывать метод set_rlim (или set_ylim) перед set_rscale (или set_yscale). Кроме того, вы должны вызвать set_rlim или set_ylim с 0 или 0,0 в качестве нижнего предела. Другие значения нижнего предела также приведут к сбою. Проблема возникает и с другими бэкендами (я подтвердил проблему с бэкендами gtkagg и pdf).

Я подал отчет об ошибке для этой проблемы, который можно найти здесь. Если эта проблема касается вас, перейдите на страницу отчета об ошибке и оставьте комментарий, чтобы сообщить разработчикам matplotlib, что эта проблема важна для пользователей.

person Craig Finch    schedule 22.03.2013

Обновлено с помощью matplotlib v3.3.4

  • Обновите def scatter_logpolar_mpl, чтобы использовать 'symlog', поскольку использование 'log' приводит к posx and posy should be finite values и пустому графику для 'log-polar matplotlib'.
# updated function with symlog
def scatter_logpolar_mpl(ax, theta, r):
    ax.scatter(theta, r)
    ax.set_rlim(0)
    ax.set_rscale('symlog')
    ax.set_title('log-polar matplotlib')

# use other unchanged original functions

# setup the plot
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), figsize=(12, 7))[1].flatten()
scatter_polar_mpl(ax[0], theta, r)
scatter_logpolar_mpl(ax[1], theta, r)
scatter_logpolar(ax[2], theta, r)

plt.tight_layout()
plt.show()

введите здесь описание изображения

Оригинальный ответ

Есть больше проблем с текущими графиками matplotlib и log-polar.

Например, попробуйте добавить небольшое значение к радиусу в примере matplotlib для полярных графики, а затем используйте set_rlim(0) и set_rscale('log') для построения графика (как было предложено в комментариях здесь). Все значения ниже 0,1 обрабатываются особым образом. Это влияет на отметки на оси r (обратите внимание на совершенно неуместные 10e-2 и 10e-3), а также на данные графика:

Примеры полярных и лог-полярных графиков

Поведение кажется недокументированным. В итоге я выполнил логарифмическое преобразование вручную (третий график в серии выше). Для других, столкнувшихся с этой темой, вот мой код:

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()
person hannes    schedule 29.09.2013

Когда я убираю комментарий в строке, которая устанавливает окно графика, он запускается для меня.

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() 
person roadrunner66    schedule 17.02.2013
comment
Я пробовал set_rscale и set_ylim, и линии сетки не отображаются. Также не отображаются некоторые очень маленькие координаты (r ~ 0,02). Интересно, была ли ошибка введена в какой-то момент? - person Evan Zamir; 01.11.2016

Установите rscale после set_ylim(), как тета ответила в комментариях выше.

person Dave    schedule 18.02.2013