Matplotlib basemap: Popup box

前端 未结 1 1415
旧巷少年郎
旧巷少年郎 2020-12-05 12:23

I want to know how to create a popup box in a basemap plot. When I hover my mouse over a location , it should trigger the popup box.

Is this possible?

相关标签:
1条回答
  • 2020-12-05 12:58

    Yes it is possible thanks to matplotlib's event handling framework. I couldn't find an already written example which does what you are particularly interested in so I wrote one (which I will put forward for inclusion in the matplotlib source).

    I would read http://matplotlib.sourceforge.net/users/event_handling.html thoroughly to best understand what is going on. Please note that although it sounds like the perfect solution "pick_event" is for mouse clicks -not for mouse over- events and doesn't work in this case.

    My code, which could be objectified very nicely should one want, looks like:

    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = plt.axes()
    
    
    points_with_annotation = []
    for i in range(10):
        point, = plt.plot(i, i, 'o', markersize=10)
    
        annotation = ax.annotate("Mouseover point %s" % i,
            xy=(i, i), xycoords='data',
            xytext=(i + 1, i), textcoords='data',
            horizontalalignment="left",
            arrowprops=dict(arrowstyle="simple",
                            connectionstyle="arc3,rad=-0.2"),
            bbox=dict(boxstyle="round", facecolor="w", 
                      edgecolor="0.5", alpha=0.9)
            )
        # by default, disable the annotation visibility
        annotation.set_visible(False)
    
        points_with_annotation.append([point, annotation])
    
    
    def on_move(event):
        visibility_changed = False
        for point, annotation in points_with_annotation:
            should_be_visible = (point.contains(event)[0] == True)
    
            if should_be_visible != annotation.get_visible():
                visibility_changed = True
                annotation.set_visible(should_be_visible)
    
        if visibility_changed:        
            plt.draw()
    
    on_move_id = fig.canvas.mpl_connect('motion_notify_event', on_move)
    
    plt.show()
    

    Hopefully everything should be fairly readable. A high level overview of the code goes:

    • Create a list of [point, annotation] pairs, where by default the annotation is not visible
    • Register a function, "on_move", to be called every time there is mouse motion detected
    • The on_move function iterates through each point and annotation, if the mouse is now over one of the points, make its associated annotation visible, if it is not, make it invisible. (the contains method is documented here)

    Screenshot of the result

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