pythonhtmlmatplotlibscatter-plotmplcursors

Is there a way to see the coordinates of a matplotlib scatterplot graph when doing a mouse over in HTML


My first issue was to create check the coordinates of the points in scatterplot matplotlib with a mouse over, that part has been done with the code:

from pandas.api.types import is_numeric_dtype
import matplotlib.pyplot as plt
import mplcursors

....
....

df.plot.scatter(x='column1', y='column2')
mplcursors.cursor(hover=True)

then i put the image in html code using this code:

plt.savefig('C:\\Users\\foo.png', bbox_inches='tight')

page_title_text = 'My report'
title_text = 'title'
text = 'Hello, welcome to your report'

html = f'''
    <html>
        <head>
            <title>{page_title_text}</title>
        </head>
        <body>
            <h1>{title_text}</h1>
            <p>{text}</p>
            <img src='C:\\Users\\foo.png' width="700">
        </body>
    </html>
    '''
with open('C:\\Users\\html_report.html', 'w') as f:
    f.write(html)

That last part allowed me to load the image in a standalone html page but obviously the mouse over won't work in this case since I'm loading a static image to the html, but is there any way at all to do this without a continuous connection to python, as in have a stand alone html that would allow to see the coordinates of scatterplot dots when having a mouse over?

EDIT

import matplotlib.pyplot as plt, mpld3

.
.
.

f= plt.gcf()
print(mpld3.fig_to_html(f))

then i wrote down the print to a file and saved as .html, as described in my comment i was able to see my plot in html but not the coordinates when doing a mouse over the dots.


Solution

  • Matplotlib generates static HTML but there is module mpld3 which use Matplotlib with JavaScript module D3.js to create interactive plot in HTML.

    It has also plugins to add some functions. i.e.

    You can find more plugins with source code on GitHub in plugins.py

    You may use this to create own plugin but this need to know JavaScript.


    Minimal working example

    import numpy as np
    import matplotlib.pyplot as plt
    import mpld3
    
    np.random.seed(0)
    
    x, y = np.random.rand(2, 10)
    fig, ax = plt.subplots()
    
    scatter = ax.scatter(x, y, s=20, c='orange')
    labels = [f'x: {a}<br>y: {b}' for a, b in zip(x, y)]
    
    position = mpld3.plugins.MousePosition()
    mpld3.plugins.connect(fig, position)
    
    #tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
    tooltip = mpld3.plugins.PointHTMLTooltip(scatter, labels=labels, 
                                             hoffset=20, voffset=20, 
                                             css='.mpld3-tooltip{background-color: #cbc; padding: 15px}')
    mpld3.plugins.connect(fig, tooltip)
    
    #mpld3.plugins.connect(fig, position, tooltip)
    
    mpld3.show()
    

    enter image description here


    EDIT:

    Code for two plots.

    The only problem: both plots has the same class .mpld3-tooltip in HTML so css=... set the same color for both plots.

    import numpy as np
    import matplotlib.pyplot as plt
    import mpld3
    
    np.random.seed(0)
    
    fig, (ax1, ax2) = plt.subplots(ncols=2)  # `ax1, ax2` has to be with `( )`
    
    #fig, all_ax = plt.subplots(ncols=2)
    #ax1, ax2 = all_ax
    
    # ---
    
    x, y = np.random.rand(2, 10)
    scatter1 = ax1.scatter(x, y, s=20, c='orange')
    labels1 = [f'x: {a}<br>y: {b}' for a, b in zip(x, y)]
    
    tooltip1 = mpld3.plugins.PointHTMLTooltip(scatter1, labels=labels1, 
                                             hoffset=20, voffset=20, 
                                             css='.mpld3-tooltip{background-color: #cbc; padding: 15px}')
    mpld3.plugins.connect(fig, tooltip1)
    
    # ---
    
    x, y = np.random.rand(2, 10)
    scatter2 = ax2.scatter(x, y, s=50, c='blue')
    labels2 = [f'x: {a}<br>y: {b}' for a, b in zip(x, y)]
    
    tooltip2 = mpld3.plugins.PointHTMLTooltip(scatter2, labels=labels2, 
                                             hoffset=20, voffset=20, 
                                             css='.mpld3-tooltip{background-color: #fcc; padding: 15px}')
    mpld3.plugins.connect(fig, tooltip2)
    
    # ---
    
    mpld3.show()