【问题标题】:How to show labels on map on mouse click/hover?如何在鼠标单击/悬停时在地图上显示标签?
【发布时间】:2018-09-06 18:24:59
【问题描述】:

我在 Python 中使用 Basemap 绘制了一系列经纬度对。示例图片为:

当鼠标在点上单击(或悬停)时,我需要显示地点的名称。我有包含纬度-经度对的文件的站名。

首先,如何在 Basemap 中实现悬停功能(或更好的功能)? 其次,当点悬停时如何将文本添加为​​标签?

这是我目前所拥有的:

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

lattd, lngtd = [], []

# latitude, longitude and station names are as headers rows(rows starting with "#", in plot_file.txt. 
# read all the lines and make lists for latitude and longitude

inputfile =  open('data-por-IN/plot_file.txt', 'r')   
for i, line in enumerate(inputfile):    
    if line.startswith('#'):
        lattd.append(int(line[56:62])/10000)
        lngtd.append(int(line[65:71])/10000)

m = Basemap(width=4000000,height=4000000,projection='lcc',
            resolution='c',lat_1=45.,lat_2=55,lat_0=20,lon_0=80.)
m.drawmapboundary(fill_color='aqua')
m.drawcountries()
m.drawcoastlines(linewidth=0.50)
m.fillcontinents(color='green', alpha = 0.6, lake_color='aqua')
for i in range(len(lngtd)):
    lon = lngtd[i] #77.580643
    lat = lattd[i] #12.972442 
    xpt,ypt = m(lon,lat)
    lonpt, latpt = m(xpt,ypt,inverse=True)
    m.plot(xpt,ypt,'yo')
    ax.bluemarble()

plt.show()

【问题讨论】:

  • 到目前为止你有什么尝试过的吗?您是否能够在没有底图的情况下实现单点悬停效果?如果不是,为什么要问这个复杂的案例?如果是这样,将其扩展到您的案例有什么问题?

标签: python matplotlib plot matplotlib-basemap


【解决方案1】:

手头的问题可以通过matplotlib event handling、annotations 和(用于图形大小独立标记拾取)transformations 来解决。下面是一个示例,当鼠标指针移动到其中一个蓝色标记的顶部时,它会显示一个标签。由于标记大小以磅为单位(一个点为 1/72 英寸),我将数据坐标转换为图形坐标,遵循matplotlib transformation tutorial 中的阴影效果转换。希望这会有所帮助。

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import math


# latitude, longitude and station names are as headers rows(rows starting with "#", in plot_file.txt. 
# read all the lines and make lists for latitude and longitude

##inputfile =  open('data-por-IN/plot_file.txt', 'r')   
##for i, line in enumerate(inputfile):    
##    if line.startswith('#'):
##        lattd.append(int(line[56:62])/10000)
##        lngtd.append(int(line[65:71])/10000)

##fake coordinates and labels
lattd, lngtd, labels = zip(*[
    (20.6, 79.0, 'point 1'),
    (21.3, 77.5, 'point 2'),
    (13.0, 77.6, 'point 3'),
])

##a list for keeping track of all annotations
annotations = [None for label in labels]

##defining size of markers:
markersize = 5
markersize_inches = markersize/72.

##setting up figure
fig, ax = plt.subplots()
m = Basemap(
    width=4000000,height=4000000,projection='lcc',
    resolution='c',lat_1=45.,lat_2=55,lat_0=20,lon_0=80.,
    ax = ax,
)
m.drawcountries()
m.drawcoastlines(linewidth=0.50)
m.bluemarble()

##data coordinates
xdata, ydata = zip(*[m(lon,lat) for lon,lat in zip(lngtd,lattd)])
ax.plot(xdata,ydata,'bo', mec='k', ms = markersize)

##figure coordinates in inches
trans = ax.transData+fig.dpi_scale_trans.inverted()

##function for checking mouse coordinates and annotating
def on_move(event):
    if event.inaxes:
        x0, y0 = trans.transform((event.xdata, event.ydata))
        xfig, yfig = zip(*[trans.transform((x,y)) for x,y in zip(xdata,ydata)])
        dists = [math.sqrt((x-x0)**2+(y-y0)**2) for x,y in zip(xfig, yfig)]

        for n,(x,y,dist,label) in enumerate(zip(xdata,ydata,dists, labels)):
            if dist < markersize_inches and annotations[n] is None:
                annotations[n]=ax.annotate(
                    label,
                    [x,y], xycoords='data',
                    xytext = (10,10), textcoords='offset points',
                    ha='left', va='center',
                    bbox=dict(facecolor='white', edgecolor='black', boxstyle='round'),
                    zorder=10,
                )
                fig.canvas.draw()

            elif dist > markersize_inches and annotations[n] is not None:
                annotations[n].remove()
                annotations[n] = None
                fig.canvas.draw()

##connecting the event handler
cid = fig.canvas.mpl_connect('motion_notify_event', on_move)


plt.show()

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2023-04-03
    • 2017-03-06
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    相关资源
    最近更新 更多