matplotlib和地理数据图的长宽比

时间:2013-09-18 13:30:50

标签: python matplotlib aspect-ratio gis

我处理地理信息并使用表示结果 matplotlib。所有输入都是纬度/经度[度]。我转换成 x / y [米]用于我的计算。我把结果展示出来了 lattitude /经度。问题是获得图长宽比 右:所有图表都太宽。是否有标准程序来设置 正确的宽高比,所以我可以简单地绘制我的散点图和其他图 使用lat / lon并且结果具有正确的形状?在屏幕上和 纸(png)?

[稍后补充此部分] 这是我的问题的裸露剥离版本。我需要实际的纬度/经度值 围绕轴和准确的形状(方形)。现在看起来很宽(2x)。

import math
import matplotlib.pyplot as plt
import numpy as np
from pylab import *

w=1/math.cos(math.radians(60.0))
plt_area=[0,w,59.5,60.5] #60deg North, adjacent to the prime meridian

a=np.zeros(shape=(300,300))

matshow(a, extent=plt_area)

plt.grid(False)
plt.axis(plt_area)
fig   = plt.gcf()
fig.set_size_inches(8,8)
fig.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9)

plt.show()

3 个答案:

答案 0 :(得分:2)

我似乎找到了解决方案。 我在这里找到了它:How can I set the aspect ratio in matplotlib?

import math
import matplotlib.pyplot as plt
import numpy as np

w=1/math.cos(math.radians(60.0))
plt_area=[0,w,59.5,60.5] #square area

a=np.zeros(shape=(300,300))

fig = plt.figure()
ax = fig.add_subplot(111)

ax.imshow(a)

plt.grid(False)
ax.axis(plt_area)
fig   = plt.gcf()
fig.set_size_inches(8,8)
ax.set_aspect(w)
fig.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9)

plt.show()

答案 1 :(得分:0)

在matplotlib中,我通常会改变数字大小:

import matplotlib.pyplot as plt

plt.clf()
fig     = plt.figure()
fig_p   = plt.gcf()
fig_p.set_size_inches(8, 8)    # x, y

但是,这会设置图形外部尺寸的尺寸,而不是绘图区域。您可以分别更改相对于图形大小的绘图区域,该大小分别以x和y的总图形长度比率给出:

fig.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9)

只要相对比率保持对称,则曲线的长宽比应该相同。

示例1:

plt.clf()
fig     = plt.figure()
fig_p   = plt.gcf()
fig_p.set_size_inches(5, 5)    # x, y for figure canvas

# Relative distance ratio between origin of the figure and max extend of canvas
fig.subplots_adjust(left=0.2, right=0.8, bottom=0.2, top=0.8)

ax1   = fig.add_subplot(111)
xdata = [rand()*10 for i in xrange(100)]
ydata = [rand()*1  for i in xrange(100)]
ax1.plot(xdata, ydata, '.b', )
ax1.set_xlabel('Very Large X-Label', size=30)
plt.savefig('squareplot.png', dpi=96)

$.subplot_adjust$ overwrites the default space between figure size and plot extend

示例2:

fig.subplots_adjust(left=0.0, right=1.0, bottom=0.0, top=1.0)

绘图区域完全填充图形大小:

No spacing between figure size and plot area

答案 2 :(得分:0)

请勿尝试通过摆弄fig.set_size_inches()fig.subplots_adjust()或更改数据来解决此问题;而是使用墨卡托投影。

通过使用数据平均纬度的余弦倒数的纵横比,可以获得快速而脏的墨卡托投影。这是非常好的"对于包含在大约1度纬度中的数据,大约100度。 (你必须决定,对于你的应用来说,这是否足够好"如果它不是,你真的必须考虑一些严肃的地理投影库.. 。)

示例:

from math import cos, radians
import matplotlib.pyplot as plt
import numpy as np

# Helsinki 60.1708 N, 24.9375 E
# Helsinki (lng, lat)
hels = [24.9375, 60.1708]
# a point 100 km directly north of Helsinki
pt_N = [24.9375, 61.0701]
# a point 100 km east of Helsinki along its parallel
pt_E = [26.7455, 60.1708]

coords = np.array([pt_N, hels, pt_E])

plt.figure()
plt.plot(coords[:,0], coords[:,1])

# either of these will estimate the "central latitude" of your data
# 1) do the plot, then average the limits of the y-axis    
central_latitude = sum(plt.axes().get_ylim())/2.
# 2) actually average the latitudes in your data
central_latitude = np.average(coords, 0)[1]

# calculate the aspect ratio that will approximate a 
# Mercator projection at this central latitude 
mercator_aspect_ratio = 1/cos(radians(central_latitude))

# set the aspect ratio of the axes to that
plt.axes().set_aspect(mercator_aspect_ratio)

plt.show()

我选择赫尔辛基作为例子,因为在那个纬度,纵横比几乎为2 ...因为两度经度与一个纬度相同的距离

要真正看到这项工作:a)运行上面的内容,b)调整窗口大小。然后注释掉对set_aspect()的调用并执行相同的操作。在第一种情况下,保持正确的宽高比,在后者中你得到无意义的拉伸。

赫尔辛基北部和东部100公里处的点数由可移动类型脚本的优秀页面calculating distances between lat/lng points计算/确认