How to show data labels when you mouse over data

前端 未结 1 984
臣服心动
臣服心动 2020-12-19 12:14

I am plotting some data that looks like

931,Oxfordshire,9314125,123255,Larkmead School,Abingdon,125,124,20,SUPP,8
931,Oxfordshire,9314126,123256,John Mason S         


        
相关标签:
1条回答
  • 2020-12-19 12:35

    Just to plug my own project, have a look at mpldatacursor: https://github.com/joferkington/mpldatacursor

    As a basic example, just calling datacursor(hover=True, point_labels=df['E']) will get you 90% of the way to what you want. For example, taking your code snippet above:

    from StringIO import StringIO
    import pandas as pd
    import matplotlib.pyplot as plt
    from mpldatacursor import datacursor
    
    f = StringIO(
    """931,Oxfordshire,9314125,123255,Larkmead School,Abingdon,125,124,20,SUPP,8
    931,Oxfordshire,9314126,123256,John Mason School,Abingdon,164,164,25,6,16
    931,Oxfordshire,9314127,123257,Fitzharrys School,Abingdon,150,149,9,0,11
    931,Oxfordshire,9316076,123298,Our Lady's Abingdon,Abingdon,57,57,SUPP,SUPP,16
    """)
    df = pd.read_csv(f, names=['A','B','C','D','E','F','G', 'H','I','J', 'K'],
                     header=None)
    df.replace('SUPP', 3.0, inplace=True)
    df = df.convert_objects(convert_numeric=True)
    df['KG'] = df['K']*1.0/df['G']
    plt.plot(df['KG'], marker='o')
    
    datacursor(hover=True, point_labels=df['E'])
    
    plt.show()
    

    enter image description here

    We'll get a popup label whenever the line is hovered over.

    However, by design, the default behavior is to display the pop-up whenever the line is hovered over / clicked on. Therefore, when using the point_labels option, the result may not quite be what you had in mind:

    enter image description here

    If you only want the pop-up to be displayed when the vertexes are hovered over, you can use a workaround similar to this: (There will be an option for only displaying the pop-up at vertexes in the next release, so this workaround won't be required in the future.)

    from StringIO import StringIO
    import pandas as pd
    import matplotlib.pyplot as plt
    from mpldatacursor import datacursor
    
    f = StringIO(
    """931,Oxfordshire,9314125,123255,Larkmead School,Abingdon,125,124,20,SUPP,8
    931,Oxfordshire,9314126,123256,John Mason School,Abingdon,164,164,25,6,16
    931,Oxfordshire,9314127,123257,Fitzharrys School,Abingdon,150,149,9,0,11
    931,Oxfordshire,9316076,123298,Our Lady's Abingdon,Abingdon,57,57,SUPP,SUPP,16
    """)
    df = pd.read_csv(f, names=['A','B','C','D','E','F','G', 'H','I','J', 'K'],
                     header=None)
    df.replace('SUPP', 3.0, inplace=True)
    df = df.convert_objects(convert_numeric=True)
    df['KG'] = df['K']*1.0/df['G']
    plt.plot(df['KG'], marker='o')
    
    l, = plt.plot(df['KG'], marker='o', linestyle='', visible=False)
    datacursor(l, hover=True, point_labels=df['E'])
    
    plt.show()
    

    Also, you might want to only display the school in question, instead of the x,y coordinates, etc. To change this, use a custom formatter function:

    datacursor(l, hover=True, point_labels=df['E'],
               formatter=lambda **kwargs: kwargs['point_label'][0])
    

    enter image description here

    And finally, you might want a white box with a fancier arrow and a different relative position:

    datacursor(l, hover=True, point_labels=df['E'], bbox=dict(fc='white'),
               formatter=lambda **kwargs: kwargs['point_label'][0], xytext=(0, 25),
               arrowprops=dict(arrowstyle='simple', fc='white', alpha=0.5))
    

    enter image description here

    Just to put it all together into a runnable version for the last example:

    from StringIO import StringIO
    import pandas as pd
    import matplotlib.pyplot as plt
    from mpldatacursor import datacursor
    
    f = StringIO(
    """931,Oxfordshire,9314125,123255,Larkmead School,Abingdon,125,124,20,SUPP,8
    931,Oxfordshire,9314126,123256,John Mason School,Abingdon,164,164,25,6,16
    931,Oxfordshire,9314127,123257,Fitzharrys School,Abingdon,150,149,9,0,11
    931,Oxfordshire,9316076,123298,Our Lady's Abingdon,Abingdon,57,57,SUPP,SUPP,16
    """)
    df = pd.read_csv(f, names=['A','B','C','D','E','F','G', 'H','I','J', 'K'],
                     header=None)
    df.replace('SUPP', 3.0, inplace=True)
    df = df.convert_objects(convert_numeric=True)
    df['KG'] = df['K']*1.0/df['G']
    plt.plot(df['KG'], marker='o')
    
    l, = plt.plot(df['KG'], marker='o', linestyle='', visible=False)
    datacursor(l, hover=True, point_labels=df['E'], bbox=dict(fc='white'),
               formatter=lambda **kwargs: kwargs['point_label'][0], xytext=(0, 25))
    
    plt.show()
    
    0 讨论(0)
提交回复
热议问题