【问题标题】:Polar contour plot in matplotlib - best (modern) way to do it?matplotlib 中的极地等高线图 - 最好的(现代)方法?
【发布时间】:2012-02-22 16:08:56
【问题描述】:

更新:我已经在我的博客http://blog.rtwilson.com/producing-polar-contour-plots-with-matplotlib/ 上完成了关于我发现这样做的方式的完整记录 - 你可能想先查看那里。

我正在尝试在 matplotlib 中绘制极坐标等值线图。我在互联网上找到了各种资源,(a)我似乎无法让我的代码工作,并且(b)许多资源看起来很旧,我想知道现在是否有更好的方法。例如,http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg01953.html 暗示可能会做一些事情来尽快改进,那是在 2006 年!

我希望能够绘制正确的极坐标图 - 就像 pcolor 可以让你为它的绘图类型做(见下面注释掉的部分),但我似乎找不到任何方法来做到这一点,所以我先转换为笛卡尔坐标。

无论如何,我有以下代码:

from pylab import *
import numpy as np

azimuths = np.arange(0, 360, 10)
zeniths = np.arange(0, 70, 10)
values = []

for azimuth in azimuths:
  for zenith in zeniths:
    print "%i %i" % (azimuth, zenith)
    # Run some sort of model and get some output
    # We'll just use rand for this example
    values.append(rand())

theta = np.radians(azimuths)

values = np.array(values)
values = values.reshape(len(zeniths), len(azimuths))

# This (from http://old.nabble.com/2D-polar-surface-plot-td28896848.html)
# works fine
##############
# Create a polar axes
# ax = subplot(111, projection='polar')
# pcolor plot onto it
# c = ax.pcolor(theta, zeniths, values)
# show()

r, t = np.meshgrid(zeniths, azimuths)

x = r*np.cos(t)
y = r*np.sin(t)

contour(x, y, values)

当我运行它时,我收到一个错误TypeError: Inputs x and y must be 1D or 2D.。我不确定为什么会得到这个,因为 x 和 y 都是 2D 的。我做错了吗?

此外,将从模型返回的值放入列表然后对其进行重新整形似乎相当笨拙。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: python numpy matplotlib


    【解决方案1】:

    x、y 和值的形状必须相同。您的数据形状是:

    >>> x.shape, y.shape, values.shape
    ((36, 7), (36, 7), (7, 36))
    

    所以将轮廓(x,y,值)更改为轮廓(x,y,值.T)。

    【讨论】:

    • 谢谢,问题解决了。关于当前在 matplotlib 中绘制极坐标图的最佳方法,您对问题的其他部分有什么想法吗?
    【解决方案2】:

    您应该能够像往常一样在极坐标图上使用ax.contourax.contourf...不过,您的代码中有一些错误。您将事物转换为弧度,然后在绘图时使用以度为单位的值。此外,当它期望 theta, r 时,您将 r, theta 传递给轮廓。

    举个简单的例子:

    import numpy as np
    import matplotlib.pyplot as plt
    
    #-- Generate Data -----------------------------------------
    # Using linspace so that the endpoint of 360 is included...
    azimuths = np.radians(np.linspace(0, 360, 20))
    zeniths = np.arange(0, 70, 10)
    
    r, theta = np.meshgrid(zeniths, azimuths)
    values = np.random.random((azimuths.size, zeniths.size))
    
    #-- Plot... ------------------------------------------------
    fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
    ax.contourf(theta, r, values)
    
    plt.show()
    

    【讨论】:

    • 谢谢 - 这非常很有帮助。我现在几乎可以正常工作了!只需一个快速查询 - 如果可以的话。我必须遍历方位角和天顶来运行我的模型并取出我的数据(该模型涉及调用另一个 python 库)——这是我用列表做的方式,然后重塑数组,一种明智的方式做吗?有没有更pythonic的方式?
    • 有几种方法,但是如果事先不知道数组的大小,那么构建一个列表,最后变成一个数组是一个很好的解决方案。还有numpy.fromiter,如果您遇到内存问题,这很好。至于嵌套的for 循环,您可以用itertools.product 替换它们,但这在很大程度上是一个口味问题。如果您可以将事物矢量化以使用数组而不是单个值,您可能会看到加速。但是,如果您不能(由于另一个库),那么您就不能。
    • 编写一个简单的生成器(在您的情况下很可能是使用yield 的函数)而不是更“spagetti-string”的解决方案通常更简洁。模块化更好:)
    • 如何处理沿 theta=0 轴的这种丑陋的插值下降?
    • @JoeKington 我可以在这里对我的问题使用相同的方法吗?scicomp.stackexchange.com/questions/28058/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 2017-07-24
    相关资源
    最近更新 更多