【问题标题】:How to use log scale on polar axis in matplotlib如何在 matplotlib 的极轴上使用对数刻度
【发布时间】:2013-02-17 08:45:39
【问题描述】:

我正在尝试在径向轴上创建一个带有对数刻度的极坐标图,但我不断收到错误消息。一些示例代码和错误如下。它似乎在笛卡尔坐标中工作正常,有人知道发生了什么吗??

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

【问题讨论】:

    标签: python matplotlib polar-coordinates


    【解决方案1】:

    更新为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 和对数极坐标图存在更多问题。

    例如,尝试为极坐标图的matplotlib example 中的半径添加一个小值,然后使用set_rlim(0)set_rscale('log') 绘制它(如cmets here 中所建议的那样)。所有低于 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()
    

    【讨论】:

      【解决方案2】:

      这似乎是 matplotlib 中的一个错误。您不必在set_rscale(或set_yscale)之前调用set_rlim(或set_ylim)方法。此外,您必须调用set_rlimset_ylim,下限为0 或0.0。下限的其他值也将导致崩溃。其他后端也会出现此问题(我已确认 gtkagg 和 pdf 后端的问题)。

      我为此问题提交了一份错误报告,可以在here 找到。如果此问题对您有影响,请前往错误报告页面并发表评论,让 matplotlib 开发人员知道此问题对用户很重要。

      【讨论】:

        【解决方案3】:

        当我在设置绘图窗口的行中取出注释时,它会为我运行。

        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_rscaleset_ylim 并没有出现网格线。还有一些非常小的坐标(r ~ 0.02)没有被绘制出来。想知道是否在某个时候引入了错误?
        【解决方案4】:

        set_ylim() 之后设置rscale,就像上面 cmets 中回答的 theta。

        【讨论】:

          猜你喜欢
          • 2013-02-21
          • 1970-01-01
          • 2019-08-25
          • 2021-11-05
          • 2015-09-02
          • 2023-02-08
          • 1970-01-01
          • 2016-07-15
          相关资源
          最近更新 更多