Drawing lines between cartopy axes

前端 未结 1 1660
轻奢々
轻奢々 2021-02-11 04:11

I have drawn two sets of axes which overlap, one being a zoomed version of the other. I want to draw lines between the corners of the zoomed axes and the corners of the rectangl

1条回答
  •  梦谈多话
    2021-02-11 04:44

    Not easily AFAIK, as you essentially want to define one point in one CS and the other in another (BlendedGenericTransform allows you to define your xs in one CS and ys in another, but not individual points).

    As a result, the only solution I know of is to construct a transform which expects a certain number of points to transform. I've implemented a 2 point transformation class which transforms the first point given the first transform, and the second point with the other transform:

    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
    

    With this I can then add a line expressed in the coordinates I care about:

    line = plt.Line2D(xdata=(-45, 0), ydata=(-15, 0),
                      transform=TwoPointTransformer(ax1.transData, ax2.transAxes))
    

    Note: I believe there to be an issue with the matplotlib caching of lines with non-affine transforms such as this. This problem manifests itself when we resize the figure. As a result, the simplest solution to this is to also add the line:

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

    Which will re-compute the line each time the figure is resized.

    This should do the trick for you.

    HTH

    0 讨论(0)
提交回复
热议问题