python polar contour_python - Polar contour plot in matplotlib - best (modern) way to do it?

Update: I've done a full write-up of the way I found to do this on my blog at http://blog.rtwilson.com/producing-polar-contour-plots-with-matplotlib/ - you may want to check there first.

I'm trying to plot a polar contour plot in matplotlib. I've found various resources on the internet, (a) I can't seem to get my code to work and (b) many of the resources appear rather old, and I'm wondering if there is a better way now. For example, http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg01953.html suggests that something may be done to

things soon, and that was in 2006!

I'd love to be able to plot proper polar contour plots - like pcolor lets you do for its type of plot (see commented out section below), but I can't seem to find any way to do that, so I'm converting to cartesian co-ordinates first.

Anyway, I have the code that follows:

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)

When I run that I get an error TypeError: Inputs x and y must be 1D or 2D.. I'm not sure why I get this, as both x and y are 2D. Am I doing something wrong?

Also, it seems rather clunky to be putting my values returned from my model into a list and then reshaping it. Is there a better way to do this?

python numpy matplotlib

|

this question

edited Apr 11 '12 at 18:07

asked Jan 30 '12 at 21:33

robintw

9,3242587155

|

2 Answers

2

---Accepted---Accepted---Accepted---

You should just be able to use ax.contour or ax.contourf with polar plots just as you normally would...

You have a few bugs in your code, though.

You convert things to radians, but then use the values in degrees when you plot.

Also, you're passing in r, theta to contour when it expects theta, r.

As a quick example:

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

|

this answer

answered Jan 31 '12 at 16:20

Joe Kington

111k17261282

Thanks - that's very helpful. I've pretty much got it working now! Just one quick query - if that's ok. I have to loop through the azimuths and zeniths to run my model and get out my data (the model involves calling another python library) - is the way I'm doing it with a list, and then reshaping the array, a sensible way to do it? Is there a more pythonic way?

– robintw

Jan 31 '12 at 21:16

There are several ways, but if you don't know the size of the array before-hand, then building a list and turning it into an array at the end is a very good solution.

There's also numpy.fromiter, which is nice if you're running into memory problems.

As far as the nested for loops, you could replace them with itertools.product, but that's largely a matter of taste.

If you could vectorize things to work with an array instead of a single value, you'd probably see a speedup. If you can't (due to the other library) then you can't, though.

– Joe Kington

Jan 31 '12 at 23:39

It is often cleaner to write a simple generator (Most likely a function using yield, in your case) instead of a more "spagetti-string" solution, though.

Modular is better :)

– Joe Kington

Jan 31 '12 at 23:41

|

the shape of x, y and values must be the same. Your data shape is:

>>> x.shape, y.shape, values.shape

((36, 7), (36, 7), (7, 36))

so change contour(x, y, values) to contour(x, y, values.T).

|

this answer

answered Jan 31 '12 at 2:03

HYRY

41.1k65887

Thanks, that solved the problem. Do you have any ideas about the other parts of the question regarding the current best way to do polar contour plots in matplotlib?

– robintw

Jan 31 '12 at 8:56

|

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值