Dynamically serving a matplotlib image to the web using python

后端 未结 6 1497
悲哀的现实
悲哀的现实 2020-11-29 02:43

This question has been asked in a similar way here but the answer was way over my head (I\'m super new to python and web development) so I\'m hoping there\'s a simpler way o

6条回答
  •  醉梦人生
    2020-11-29 03:45

    I know I'm a bit late to the party here, but I had this same problem and ended up with the small script below.

    This python 3.6+ code:

    • Starts a web server and tells you where to view it
    • Scans itself for class methods beginning with 'plot_' and provides the browser with a list of plots
    • For a clicked plot, prompts for required parameters (if any), including an automatic refresh period (in seconds)
    • Executes the plot and refreshes

    As you can tell by the code, it is deliberately minimal for temporary diagnostics and monitoring (of machine learning progress in my case).

    You may need to install any dependencies (plac + any other libs needed for plotting e.g. I use pandas, matplotlib)

    You can run the file via double click (no parameters) or command line (with/without parameters)

    Code:

    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    import io
    from http.server import HTTPServer,BaseHTTPRequestHandler
    import urllib
    import inspect
    
    
    class PlotRequestHandler(BaseHTTPRequestHandler):
    
        def do_GET(self):
            args = urllib.parse.parse_qs(self.path[2:])
            args = {i:args[i][0] for i in args}
            html = ''
    
            if 'mode' not in args:
                plots = ''
                for member in dir(self):
                    if member[:5] == 'plot_':
                        plots += f'{member[5:].replace("_"," ").title()}
    \n' html = f'''

    Available Plots

    {plots}''' elif args['mode'] == 'paramcheck': plotargs = inspect.getargspec(getattr(self,args['graph'])).args if len(plotargs) == 1 and plotargs[0].lower()=='self': args['mode'] = 'plotpage' else: for arg in plotargs: if arg.lower() != 'self': html += f"
    \n" html = f"

    Parameters:

    {html}(Refresh in sec)
    " if 'mode' in args and args['mode'] == 'plotpage': html = f''' ''' elif 'mode' in args and args['mode'] == 'plot': try: plt = getattr(self,args['graph'])(*tuple((args[arg] for arg in inspect.getargspec(getattr(self,args['graph'])).args if arg in args))) self.send_response(200) self.send_header('Content-type', 'image/png') self.end_headers() plt.savefig(self.wfile, format='png') except Exception as e: html = f"

    Error:

    {e}" if html != '': self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(bytes(html,'utf-8')) def plot_convergence(self, file_path, sheet_name=None): if sheet_name == None: data = pd.read_csv(file_path) else: data = pd.read_excel(file_path, sheet_name) fig, ax1 = plt.subplots() ax1.set_xlabel('Iteration') ax1.set_ylabel('LOSS', color='tab:red') ax1.set_ylim([0,1000]) ax1.plot(data.iteration, data.loss, color='tab:red') ax2 = ax1.twinx() ax2.set_ylabel('Precision, Recall, f Score') ax2.set_ylim([0,1]) ax2.plot(data.iteration, data.precision, color='tab:blue') ax2.plot(data.iteration, data.recall, color='tab:green') ax2.plot(data.iteration, data['f-score'], color='tab:orange') fig.tight_layout() plt.legend(loc=6) return plt def main(server_port:"Port to serve on."=9999,server_address:"Local server name."=''): httpd = HTTPServer((server_address, server_port), PlotRequestHandler) print(f'Serving on http://{httpd.server_name}:{httpd.server_port} ...') httpd.serve_forever() if __name__ == '__main__': import plac; plac.call(main)

提交回复
热议问题