2

オーバーラップする 2 つの軸セットを描画しました。1 つはもう 1 つのズーム バージョンです。ズームされた軸の角と、それが大きな軸で表す長方形の角の間に線を引きたいと思います。ただ、描いている線が少しずれています。これを簡単な例に要約しようとしました:

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()て、縦横比がマップの縦横比と一致し、線が期待どおりの場所に描画されるようにすることはできますが、これは簡単ではありません。座標変換でこれを説明できる方法はありますか?

4

1 に答える 1

3

基本的にあるCSで1つのポイントを定義し、別のCSで別のポイントを定義したいので、簡単にはわかりません(BlendedGenericTransformを使用すると、1つのCSでxを定義し、別のCSでyを定義できますが、個々のポイントは定義できません)。

その結果、私が知っている唯一の解決策は、特定の数のポイントが変換されることを期待する変換を構築することです。最初の変換で最初のポイントを変換し、2 番目のポイントを別の変換で変換する 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 キャッシュに問題があると思います。この問題は、Figure のサイズを変更すると明らかになります。結果として、これに対する最も簡単な解決策は、次の行も追加することです。

fig.canvas.mpl_connect('resize_event', lambda v: line.recache())

フィギュアのサイズが変更されるたびに線を再計算します。

これでうまくいくはずです。

HTH

于 2014-03-21T10:24:15.857 に答える