Python画极坐标图
需要⽤Python画极坐标等值线图,以下是所学的⼀些东西,特此记录
--------------------------------------------------
翻译⾃
你应该能够像往常⼀样使⽤极地图的ax.contour或ax.contourf 。单位是弧度,传递函数的顺序是,theta,r
import numpy as np
import matplotlib.pyplot as plt
#-- Generate Data -----------------------------------------
# Using linspace so that the endpoint of 360
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))
#-- ------------------------------------------------
fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
plt.show()
结果
翻译⾃
创建⼀些极坐标轴,在上⾯绘制轮廓图:
fig, ax =subplots(subplot_kw=dict(projection='polar'))
cax =ax.contourf(theta, r, values, nlevels)
这个利⽤了contourf函数,产⽣了⼀个填充的轮廓图,使⽤轮廓函数可以得到简单的轮廓线。这个函数的前三个参数必须被被给定,它们都是⼆维数组,包含:半径raddi,⾓度(theta)和轮廓的实际值。最后⼀个参数是要绘制的轮廓的层次数——如果希望得到等值线图,则数字可以⼩⼀些,如果希望得到填充的等值线图,则数字需要⼤⼀些(以获得平滑的外观)。(如果希望最外⾯的轮廓⾜够圆,则需要⽹格点⾜够密集)
我从来没有完全理解这些⼆维数组,以及为什么需要它们。我通常以三个列表的形式获得我的数据,这些列表基本上是表的列,其中表的每⼀⾏都定义了⼀个点和值。例如:
Radius Theta Value
10 0 0.7
10 90 0.45
10 180 0.9
10 270 0.23
20 0 0.5
20 90 0.13
20 180 0.52
20 270 0.98
这些⾏中的每⼀⾏都定义⼀个点 - 例如,第⼀⾏定义半径为10的点,⾓度为0度,值为0.7。我永远⽆法理解为什么轮廓功能不只是采⽤这三个列表并绘制⼀个等⾼线图。事实上,我已经编写了⼀个函数来完成这个,我将在下⾯描述,但⾸先让我解释⼀下这些值是如何转换为⼆维数组的。
⾸先,让我们想⼀想维数:我们的数据中显然有维数,半径和⾓度。事实上,我们可以重新塑造我们的数值数组,使得它变成⼆维的。我们可以从上表中看到,我们正在做半径为10度的所有⽅位⾓,然后是
半径为20度的相同⽅位⾓,等等。因此,我们的值不是存储在⼀维列表中,我们可以把它们放在⼀个⼆维表中,其中列是⽅位⾓,⾏是半径:
0 90 180 270
10 0.70.450.90.23
20 0.50.130.520.98
这正是我们需要为contourf函数赋予的那种⼆维数组。这并不难理解——但为什么地球上的半径和⾓度数组也必须是⼆维的。好吧,基本上我们只需要两个像上⾯那样的数组,但是在对应的单元格中有相应的半径和⾓度,⽽不是值。所以,对于⾓度,我们有:
0 90 180 270
10 090180270
20 090180270
对于半径,我们有:
0 90 180 270
10 10101010
20 0202020
然后,当我们将所有三个数组放在⼀起时,每个单元格将定义我们需要的三个信息。因此,左上⾓的单元格给出的⾓度为0,半径为10,值为0.7。幸运的是,你不必⼿动制作这些数组——⼀个名为meshgrid的⽅便的NumPy函数会为你做:
>>> radii = np.arange(0, 60, 10)
>>> print(radii)
[ 010********]
>>> angles = np.arange(0, 360, 90)
>>> print(angles)
[ 090180270]
>>> np.meshgrid(angles, radii)
[array([[ 0, 90, 180, 270],
[ 0, 90, 180, 270],
[ 0, 90, 180, 270],
[ 0, 90, 180, 270],
[ 0, 90, 180, 270],
[ 0, 90, 180, 270]]), array([[ 0, 0, 0, 0],
[10, 10, 10, 10],
[20, 20, 20, 20],
[30, 30, 30, 30],
[40, 40, 40, 40],
[50, 50, 50, 50]])]
要记住的⼀点是绘图函数需要以弧度⽽不是度数作为的⾓度(θ)的单位,因此如果您的数据是以度为单位(通常是),那么您需要使⽤NumPy radians函数将其转换为弧度。
完成所有这些操作后,您可以正确地将数据导⼊轮廓绘图功能,并且可以获得⼀些极轴,以便绘制它。但是,如果你这样做,你会发现你的轴看起来像这样:
您可以看到零度不在顶部,它位于“东”或“3点”位置,并且⾓度绕错了⽅向!显然,这些事情通常都是在数学中完成的——但在我的领域,特别是⼈们希望有⼀个顶部为零像指南针⼀样的极坐标情景!
如果您尝试到如何执⾏此操作,您将到⼀个,其中包含PolarAxes的精彩⼦类,可以解决这个问题。很赞的是,matplotlib允许你进⾏这种私⼈定制,但是如果你看下⾯接受的答案,你会到⼀个名为的函数的matplotlib⽂档的链接。这个功能⾮常好地采⽤指南针⽅向(“N”或“E”或“NE”等)为零!类似地,函数设置⾓度增加的⽅向。您需要做的就是从轴对象中调⽤它们:
ax.set_theta_zero_location("N")
ax.set_theta_direction(-1)
上⾯的⽰例将为“正常”罗盘样式绘图设置图,北部为零度,并且⾓度顺时针增加。如果您发现这些代码⾏出现错误,则需要更新matplotlib版本——这些⽅法仅在最新版本(v1.1.0)中添加。
所以,现在我们已经涵盖了我逐渐学到的所有这些,我们可以把它们放在⼀个函数中。每当我想要绘制⼀个极坐标等⾼线图时,我都会使⽤下⾯的函数,它对我来说很好。
我不能保证代码对你有⽤,但希望这篇⽂章有⽤,你现在可以离开并在matplotlib中创建极坐标等⾼线图。
1import numpy as np
2from matplotlib.pyplot import *
3
4def plot_polar_contour(values, azimuths, zeniths):
5"""Plot a polar contour plot, with 0 degrees at the North.
6
7 Arguments:
8
9 * `values` -- A list (or other iterable - eg. a NumPy array) of the values to plot on the
10 contour plot (the `z` values)
11 * `azimuths` -- A list of azimuths (in degrees)
12 * `zeniths` -- A list of zeniths (that is, radii)
13
14 The shapes of these lists are important, and are designed for a particular
15 use case (but should be more generally useful). The values list should be `len(azimuths) * len(zeniths)`
16 long with data for the first azimuth for all the zeniths, then the second azimuth for all the zeniths etc.
17
18 This is designed to work nicely with data that is produced using a loop as follows:
19
20 values = []
21 for azimuth in azimuths:
22 for zenith in zeniths:
23 # Do something and get a result
24 values.append(result)
25
26 After that code the azimuths, zeniths and values lists will be ready to be passed into this function.
27
28"""
29 theta = np.radians(azimuths)
30 zeniths = np.array(zeniths)
31
32 values = np.array(values)
values翻译33 values = shape(len(azimuths), len(zeniths))
34
35 r, theta = np.meshgrid(zeniths, np.radians(azimuths))
36 fig, ax = subplots(subplot_kw=dict(projection='polar'))
37 ax.set_theta_zero_location("N")
38 ax.set_theta_direction(-1)
39 autumn()
40 cax = ax.contourf(theta, r, values, 30)
41 autumn()
42 cb = lorbar(cax)
43 cb.set_label("Pixel reflectance")
44
45return fig, ax, cax
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论