python-eel / Eel

A little Python library for making simple Electron-like HTML/JS GUI apps
MIT License
6.44k stars 587 forks source link

Getting interactive plots from python #439

Closed michaelgoetze closed 3 years ago

michaelgoetze commented 3 years ago

Describe the problem I would like to use matplotlib or plotly for interactive plots using eel. I managed to get a static plot of matplotlib by sending it as base64 encoded bytes. And that works for static images. But is there any way possible to get a dynamic python interface for matplotlib (or plotly)?

Code snippet(s) Here is a working example of my approach to using matplotlib in a static way:

server.py:


import matplotlib.pyplot as plt
from io import BytesIO
import base64 
import numpy as np
import eel

@eel.expose
def plot():
    t = np.arange(0.0, 2.0, 0.01)
    s = 1 + np.sin(2*np.pi*t)
    plt.plot(t, s)

    plt.xlabel('time (s)')
    plt.ylabel('voltage (mV)')
    plt.title('About as simple as it gets, folks')
    plt.grid(True)
    buf = BytesIO()

    plt.savefig(buf, format='png', bbox_inches='tight')
    image_base64 = "data:image/png;base64," + base64.b64encode(buf.getvalue()).decode('utf-8').replace('\n', '')
    buf.close()
    print(str(image_base64))
    return str(image_base64)

# Start EEL Server
eel.init('web')
if __name__ == '__main__':
    eel.start('main.html')

web/main.html:

<html>
<head>
    <script type="text/javascript" src="/eel.js"></script>
    <script>
        async function plot(){
            let content = await eel.plot()();
            document.getElementById('img_plot').src = content;
            console.log(content)
        }
    </script>
</head>
<body>
    <button onclick="plot()">Plot</button><br>
    <img id="img_plot" src=""/>
</body>

Desktop (please complete the following information):

samuelhwilliams commented 3 years ago

Part of the original idea for Eel was to make it easier to develop visualisations that did data processing in Python and visualisation in JS, so I might suggest you rethink your strategy a bit and instead do the hard data work in Python and then send the data across to JS where you can visualise it.

michaelgoetze commented 3 years ago

That's totally fine. I just thought there might have been a way to do it.

I might suggest you rethink your strategy a bit and instead do the hard data work in Python and then send the data across to JS where you can visualise it.

This is actually exactly the reason I went for eel. I already wrote some visualization tools in js for a kind of interactive plot that was just not possible in python/matplotlib. But if there would have been a way to combine the strength of these two approaches, it would have been even better.

I can still show plots using matplotlib for now (works for SVG as well) and that is fine. I guessed already that I might not have been possible though. Thanks for replying.