This article was last updated on <span id="expire-date"></span> days ago, the information described in the article may be outdated.
最近在研究如何从卫星数据中获取雾区数据的问题,有一个大难点就是双通道法反演时如何设置阈值的问题。最直接的方法就是先画一张不设置阈值的图,然后根据坐标打印一下数值,再设置一下阈值。但是这样来来回回要重复跑很多遍代码,为了简化工作量,便研究了一下如何通过鼠标点击图片即可打印出对应点的值。
matplotlib的点击事件
在使用matplotlib
绘图的时候,用户其实是可以定义事件监听函数的,例如窗口的ResizeEvent
事件,鼠标的MouseEvent
事件,所有的事件类型可在matplotlib手册里找到。为了实现点击取值,我们需要定义一个回调函数来在事件触发时调用。
1 | def onClick(event): |
绑定事件也很简单,例如
1 | from matplotlib import pyplot as plt |
这里button_press_event
表示鼠标的点击事件,但是没有区分右键和左键。如果想要绑定其他事件的话,需要更换该字符串。
打印出来的x和y的数值和图片里显示一致
但是我们想要的是对应点的数值,需要用取到的坐标去数据里取对应的值。然而回调函数只能传入一个必须参数,因此这里可以对回调函数重写为一个类,并使用Python的魔术方法__call__
使其可以被直接调用。
1 | class OnClick: |
需要注意这里取到的x
和y
坐标是浮点数,我们需要对其进行取整才能得到对应的数值的索引。于是绑定的代码改写如下
1 | fig.canvas.mpl_connect("button_press_event", OnClick(data)) |
对比一下旁边的colorbar
,深蓝色是小于25的,说明取值没有问题。
Cartopy地图取值
解决了matplotlib
点击取值的问题,接下来需要解决Cartopy
地图点击取值的问题。因为Cartopy
在绘图时对地理坐标系进行了操作,所以回调函数取到的坐标并不是地理坐标,而是图片的显示坐标。简单绘制个卫星数据举个例子。
那么如何获取到地理坐标呢?这个时候需要使用cartopy.mpl.geoaxes.GeoAxes
对象(也就是你的ax
)里面的projection.transform_point
方法。这个方法接受三个参数,分别是x
坐标,y
坐标以及你绘图时使用的proj
。
现在我们改写一下OnClick
类。
这里我的卫星数据是DataArray,因此取数据时需要用对应的sel方法并设置
method="nearest"
以寻找符合条件的距离最近的数值点。
1 | class OnClick: |
绑定的代码如下
1 | ax.pcolormesh(VIS['longitude'], VIS['latitude'], VIS, transform=proj) |
然后应用,看一下效果。
Author: Syize
Permalink: https://blog.syize.cn/2023/07/22/matplotlib-cartopy-on-click-event/
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Syizeのblog!
Comments