我正在尝试用 cartopy 和 matplotlib.tri 绘制一个三角形网格。我使用一个matplotlib.tri.Triangulation
对象并想用matplotlib.pyplot.triplot
.
当我将 cartopy 投影作为转换传递给 triplot 时transform=projection
,就像我绘制一条线时所做的那样,并不是所有的三角形都被绘制出来,我IndexError
在尝试保存图形时得到了一个。
另一方面,当我手动转换三角剖分中的所有点并调用 triplot 时,它可以工作。
在下面的第一个示例中,所有三角形都被绘制并且Line2D
对象没有区别。但试图挽救这个数字会引发IndexError
.
在第二个示例中,使用trilot 和手动转换后Line2D
来自 triplot 的结果对象transform=projection
在应用于其数据的转换结果方面有所不同。所以也许这是组合转换顺序的问题。
注意:我选择 PlateCarree 是为了让它尽可能简单。我对轴和数据投影的其他组合也有同样的问题。
import matplotlib.pyplot as plt
import numpy as np
from cartopy.crs import PlateCarree
from matplotlib.tri import Triangulation
plt.interactive(False)
# NB. plt.triplot returns a list of two Line2D objects in both cases
# the second of which is empty, therefore only the first is returned
def triplot_with_transform(triangulation):
"""
triangulation: matplotlib.tri.Triangulation
"""
plt.figure()
plt.subplot(projection=PlateCarree())
lines = plt.triplot(triangulation, transform=PlateCarree())
return plt.gcf(), lines[0]
def transform_before_triplot(triangulation):
"""
triangulation: matplotlib.tri.Triangulation
"""
plt.figure()
plt.subplot(projection=PlateCarree())
[x_tr, y_tr, _] = PlateCarree().transform_points(PlateCarree(),
triangulation.x,
triangulation.y).T
triangulation_tr = Triangulation(x_tr, y_tr, triangulation.triangles)
lines = plt.triplot(triangulation_tr)
return plt.gcf(), lines[0]
def compare_line2d(line1, line2):
"""
line1, line2 : matplotlib.lines.Line2D
"""
data1 = line1.get_xydata()
transform1 = line1.get_transform()
data2 = line2.get_xydata()
transform2 = line2.get_transform()
data1_ma = np.ma.masked_invalid(data1)
data2_ma = np.ma.masked_invalid(data2)
data1_tr = transform1.transform(data1)
data2_tr = transform2.transform(data2)
data1_tr_ma = np.ma.masked_invalid(data1_tr)
data2_tr_ma = np.ma.masked_invalid(data2_tr)
print 'NaNs in line data match ', np.all(data1_ma.mask == data2_ma.mask)
print 'Line data mismatch', abs(data1_ma-data2_ma).max()
print 'NaNs in transformed line data match ', np.all(data1_tr_ma.mask ==
data2_tr_ma.mask)
print 'Transformed line data mismatch', abs(data1_tr_ma-data2_tr_ma).max()
def try_so_save(fig):
try:
fig.savefig('triangulation.pdf')
except Exception as e:
print "Exception while saving figure\n", e.__repr__()
# First example, 100 vertices.
x, y = np.meshgrid(np.arange(0, 50, 5), np.arange(0, 50, 5))
tri = Triangulation(x.ravel(), y.ravel())
fig1, line1 = triplot_with_transform(tri)
fig2, line2 = transform_before_triplot(tri)
# Second example, 2500 vertices.
x, y = np.meshgrid(np.arange(0, 50), np.arange(0, 50))
tri = Triangulation(x.ravel(), y.ravel())
fig3, line3 = triplot_with_transform(tri)
fig4, line4 = transform_before_triplot(tri)
# Compare Line2D objects; since we transform from PlateCarree to
# PlateCarree, the lines should be (almost) equal.
print "Line2D objects from first example"
compare_line2d(line1, line2)
print "Line2D objects from second example"
compare_line2d(line3, line4)
# Try to save the figures.
print "Save fig1 from first example."
try_so_save(fig1)
print "Save fig3 from second example."
try_so_save(fig3)
# failing plt.savefig command to produce full traceback
fig1.savefig('triangulation.pdf')
输出是
Line2D objects from first example
NaNs in line data match True
Line data mismatch 3.5527136788e-15
NaNs in transformed line data match True
Transformed line data mismatch 0.0
Line2D objects from second example
NaNs in line data match True
Line data mismatch 7.1054273576e-15
NaNs in transformed line data match True
Transformed line data mismatch 3545.955
Save fig1 from first example.
Exception while saving figure
IndexError('Out of bounds on buffer access (axis 0)',)
Save fig3 from second example.
Exception while saving figure
IndexError('Out of bounds on buffer access (axis 0)',)
当试图保存用 创造的任何人物时transform=projection
,cartopy._crs.CRS.transform_points
会引发IndexError
。
这是 cartopy 还是 matplotlib.tri 的问题?有没有办法避免手动转换并将transform
参数传递给triplot?
编辑:
在pp-mo的回答之后,我发现在triplot命令中添加一个带有标记的格式字符串,比如'o-'
,使它工作。但是,仅仅改变颜色 ( 'g-
) 并没有帮助。
编辑2:
在示例代码中添加fig1.savefig
以产生完整的回溯。