0

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.

sara
  • 109
  • 1
  • 7
  • you should use `matplotlib` to generate HTML with JavaScript code - not image `.png` – furas Jun 03 '22 at 14:30
  • see module [mpld3](https://mpld3.github.io/quickstart.html) - it generates matplotlib plot as HTML with JavaScript code which uses library `D3.js` – furas Jun 03 '22 at 14:33
  • @furas thank you for the suggestion, I did that and was able to save it as html but i still cannot see the values of coordinates in html when doing a mouse over, please find my edit in the question. – sara Jun 05 '22 at 19:37
  • it may need to add some JavaScript code for this. Code in question [Read coordinates from mouse click in mpld3](https://stackoverflow.com/questions/25069654/read-coordinates-from-mouse-click-in-mpld3) use some `plugin` - `MousePosition()` – furas Jun 05 '22 at 19:47
  • @furas I did add that plugin and now it's even better than before as i can do a mouse over the canvas and get an approximate value, but it's a bit annoying to try to align the mouse over the exact center of the dot as no popup will be shown is there a way to adjust it where i'd get exact x,y values with mouse over especially that i read the html and the X,Y parameters are basically provided there – sara Jun 05 '22 at 20:04
  • I don't know but maybe there is other plugin for this. Eventually you may get source code for `MousePosition()` and you can try to create own version - it would have to if there is data in small distanct and display information only for this data – furas Jun 06 '22 at 11:59
  • I found example which use plugin to display label when mouse touch point (hover point) https://mpld3.github.io/examples/scatter_tooltip.html – furas Jun 06 '22 at 12:09

1 Answers1

0

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.

  • MousePosition to show current mouse positon
  • PointLabelTooltip to display tooltip (one line in plain text) when you touch/hover point
  • PointLabelTooltip to display tooltip (HTML) when you touch/hover point.
    This allow to use <br> to put items in many lines.
    It can also use CSS to set colors, margins, padding, etc.

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()
furas
  • 134,197
  • 12
  • 106
  • 148
  • it only shows how important is to create `minimal working code` which we can use to test solution. Put your code at the end of your question - it will be more readable, and more people will see it - so maybe someone else will help you. – furas Jun 09 '22 at 11:24
  • Ignore my question works perfectly per my code as well, thanks! – sara Jun 09 '22 at 11:31
  • Wondering, is there a way to display multiple ones of those graphs where i can hover over points in a single html page? – sara Jun 09 '22 at 12:14
  • `PointHTMLTooltip` gets `scatter` as parameter and I think you may create many `PointHTMLTooltip` with different `scatter` – furas Jun 09 '22 at 12:20
  • using `fig, (ax1, ax2) = plt.subplots(ncols=2)` you can create two separted plots using `s1 = ax1.scatter()` and `s2 = ax2.scatter()`. And later you can use `s1` and `s2` to create two `tooltips1`, `tooltips2` and add both to page. I see only one problem - both use the same `.mpld3-tooltip` in HTML so `css=...` will set the same color for both plots. – furas Jun 09 '22 at 12:30
  • I added example with two plots. – furas Jun 09 '22 at 12:44