我绘制了两组重叠的轴,一组是另一组的缩放版。我想在缩放轴的角和它在较大轴上代表的矩形的角之间画线。但是,我正在绘制的线条略微偏离位置。我试图将其浓缩成一个简单的例子:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
# Create a large figure:
fig = plt.figure(figsize=(10, 10))
# Add an axes set and draw coastlines:
ax1 = plt.axes([0.01, 0.49, 0.8, 0.5], projection=ccrs.PlateCarree())
ax1.set_global()
ax1.coastlines()
# Add a second axes set (overlaps first) and draw coastlines:
ax2 = plt.axes([0.45, 0.35, 0.4, 0.3], projection=ccrs.PlateCarree())
ax2.set_extent([-44, 45, -15, 45], crs=ccrs.PlateCarree())
ax2.coastlines()
# Draw the rectangular extent of the second plot on the first:
x = [-44, 45, 45, -44, -44]
y = [-15, -15, 45, 45, -15]
ax1.fill(x, y, transform=ccrs.PlateCarree(), color='#0323E4', alpha=0.5)
ax1.plot(x, y, transform=ccrs.PlateCarree(), marker='o')
# Now try and draw a line from the bottom left corner of the second axes set
# to the bottom left corner of the extent rectangle in the first plot:
transFigure = fig.transFigure.inverted()
coord1 = transFigure.transform(ax2.transAxes.transform([0, 0]))
coord2 = transFigure.transform(ax1.transData.transform([-45, -15]))
line = plt.Line2D((coord1[0], coord2[0]), (coord1[1], coord2[1]), transform=fig.transFigure)
fig.lines.append(line)
plt.show()
使用以下输出:
我认为这是因为我在调用plt.axes()
时明确定义了轴的形状/方面,并且这个形状与形状轴的形状不匹配,因为它们是以设计的宽高比绘制的地图看起来正确。我可以在调用plt.axes()
时调整轴的形状,以便宽高比与地图的宽高比相匹配,并且线条被绘制到我期望的位置,但这并不容易!有没有办法在坐标转换中解释这个问题?
答案 0 :(得分:2)
不容易AFAIK,因为您基本上想要在一个CS中定义一个点而在另一个CS中定义另一个点(BlendedGenericTransform允许您在一个CS中定义x,在另一个CS中定义y,但不是单个点)。
因此,我所知道的唯一解决方案是构造一个转换,该转换需要转换一定数量的点。我实现了一个2点变换类,它在给定第一个变换的情况下变换第一个点,在第二个点变换另一个变换:
import matplotlib.transform as mtrans
class TwoPointTransformer(mtrans.Transform):
is_affine = False
has_inverse = False
def __init__(self, first_point_transform, second_point_transform):
self.first_point_transform = first_point_transform
self.second_point_transform = second_point_transform
return mtrans.Transform.__init__(self)
def transform_non_affine(self, values):
if values.shape != (2, 2):
raise ValueError('The TwoPointTransformer can only handle '
'vectors of 2 points.')
result = self.first_point_transform.transform_affine(values)
second_values = self.second_point_transform.transform_affine(values)
result[1, :] = second_values[1, :]
return result
有了这个,我就可以添加一条用我关心的坐标表示的线:
line = plt.Line2D(xdata=(-45, 0), ydata=(-15, 0),
transform=TwoPointTransformer(ax1.transData, ax2.transAxes))
注意:我认为使用非仿射变换的matplotlib缓存存在问题。当我们调整图形大小时,这个问题就会出现。因此,最简单的解决方案是添加以下行:
fig.canvas.mpl_connect('resize_event', lambda v: line.recache())
每次调整数字时,都会重新计算线条。
这应该适合你。
HTH