如何创建极坐标等高线图。

22

更新:我在我的博客http://blog.rtwilson.com/producing-polar-contour-plots-with-matplotlib/上详细介绍了如何使用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的。我做错了什么吗?
此外,从模型返回值并将其放入列表然后重塑似乎相当笨拙。有更好的方法吗?
2个回答

26
你可以像通常一样使用 ax.contourax.contourf 来绘制极坐标图...不过你的代码中有几个问题。你将值转换为弧度,但在绘图时使用的是度数。此外,你把 r, theta 传递给等高线函数,但它期望的参数顺序是 theta, r
这里是一个快速示例:
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库) - 我使用列表然后重新整形数组的方式来做这件事,这种方法是明智的吗?是否有更符合Python风格的方法? - robintw
有几种方法,但如果您事先不知道数组的大小,则构建列表并在最后将其转换为数组是一个非常好的解决方案。还有numpy.fromiter,如果遇到内存问题,它也很好用。至于嵌套的for循环,您可以使用itertools.product替换它们,但这在很大程度上取决于个人喜好。如果您可以将事情向量化以使用数组而不是单个值,则可能会看到加速。如果由于其他库而无法执行此操作,则无法执行。 - Joe Kington
通常编写一个简单的生成器(在您的情况下,最可能是使用yield的函数)比编写更多“意大利面条式”的解决方案更加清晰。模块化更好 :) - Joe Kington
6
如何处理沿着θ=0轴的不美观插值下降? - 0x2207
1
@JoeKington,我能否在这里使用相同的方法来回答我的问题 - https://scicomp.stackexchange.com/questions/28058/calculating-curvature-from-height-contours - gansub
@JoeKington 你知道在这里添加色条的方法吗?不幸的是,当我尝试 ax.colorbar() 时,会出现错误 AttributeError:'PolarAxesSubplot'对象没有属性'colorbar' - dylnan

4

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

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

将contour(x, y, values)改为contour(x, y, values.T)。


谢谢,问题已解决。您对如何在matplotlib中实现极坐标等高线图的其他部分有什么想法吗? - robintw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接