2016-01-19 4 views
6

Ist es möglich, Plotly (innerhalb von Python verwendet) als "strikt lokal" zu verwenden? Mit anderen Worten, ist es möglich, es so zu verwenden, dass es das Netzwerk aus irgendeinem Grund nicht kontaktiert?In Python das Plotten in der Kommunikation mit dem Netzwerk in jeder Form deaktivieren

Dies beinhaltet Dinge wie das Programm, das versucht, den Plotly-Dienst zu kontaktieren (da das das Geschäftsmodell war), und Dinge wie das Klicken auf eine beliebige Stelle im generierten HTML haben auch keinen Link zu Plotly oder anderswo.

Natürlich möchte ich in der Lage sein, dies auf einer Produktionsmaschine zu tun, die an das Netzwerk angeschlossen ist, also ist das Herausziehen der Netzwerkverbindung keine Option.

+0

Haben Sie eine bessere Lösung gefunden? – LauriK

+0

@LauriK nicht so weit. – PonyEars

Antwort

1

Ich denke, ich habe eine Lösung dafür gefunden. Zuerst müssen Sie die Open Source Plotly.js file herunterladen. Dann habe ich eine Funktion, die unten geschrieben wird, die das Javascript aus dem Python-Plot erzeugt und auf Ihre lokale Kopie von plotly-latest.min.js verweist. Siehe unten:

import sys 
import os 
from plotly import session, tools, utils 
import uuid 
import json 

def get_plotlyjs(): 
    path = os.path.join('offline', 'plotly.min.js') 
    plotlyjs = resource_string('plotly', path).decode('utf-8') 
    return plotlyjs 


def js_convert(figure_or_data,outfilename, show_link=False, link_text='Export to plot.ly', 
      validate=True): 

    figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) 

    width = figure.get('layout', {}).get('width', '100%') 
    height = figure.get('layout', {}).get('height', 525) 
    try: 
     float(width) 
    except (ValueError, TypeError): 
     pass 
    else: 
     width = str(width) + 'px' 

    try: 
     float(width) 
    except (ValueError, TypeError): 
     pass 
    else: 
     width = str(width) + 'px' 

    plotdivid = uuid.uuid4() 
    jdata = json.dumps(figure.get('data', []), cls=utils.PlotlyJSONEncoder) 
    jlayout = json.dumps(figure.get('layout', {}), cls=utils.PlotlyJSONEncoder) 

    config = {} 
    config['showLink'] = show_link 
    config['linkText'] = link_text 
    config["displaylogo"]=False 
    config["modeBarButtonsToRemove"]= ['sendDataToCloud'] 
    jconfig = json.dumps(config) 

    plotly_platform_url = session.get_session_config().get('plotly_domain', 
                  'https://plot.ly') 
    if (plotly_platform_url != 'https://plot.ly' and 
      link_text == 'Export to plot.ly'): 

     link_domain = plotly_platform_url\ 
      .replace('https://', '')\ 
      .replace('http://', '') 
     link_text = link_text.replace('plot.ly', link_domain) 


    script = '\n'.join([ 
     'Plotly.plot("{id}", {data}, {layout}, {config}).then(function() {{', 
     ' $(".{id}.loading").remove();', 
     '}})' 
    ]).format(id=plotdivid, 
       data=jdata, 
       layout=jlayout, 
       config=jconfig) 

    html="""<div class="{id} loading" style="color: rgb(50,50,50);"> 
       Drawing...</div> 
       <div id="{id}" style="height: {height}; width: {width};" 
       class="plotly-graph-div"> 
       </div> 
       <script type="text/javascript"> 
       {script} 
       </script> 
       """.format(id=plotdivid, script=script, 
          height=height, width=width) 

    #html = html.replace('\n', '') 
    with open(outfilename, 'wb') as out: 
     #out.write(r'<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>') 
     out.write(r'<script src="plotly-latest.min.js"></script>') 
     for line in html.split('\n'): 
      out.write(line) 

     out.close() 
    print ('JS Conversion Complete') 

Die wichtigsten Linien, die alle wegnimmt Links sind:

config['showLink'] = show_link #False 
.... 
config["modeBarButtonsToRemove"]= ['sendDataToCloud'] 

Sie die fuction als solche bezeichnen würde eine statische HTML-Datei zu erhalten, die Ihre lokale Kopie von plotly verweist Open sourced Bibliothek:

fig = { 
"data": [{ 
    "x": [1, 2, 3], 
    "y": [4, 2, 5] 
}], 
"layout": { 
    "title": "hello world" 
} 
} 
js_convert(fig, 'test.html') 
+0

Danke, das ist hilfreich. Mein Zweck beim Stellen der Frage bestand hauptsächlich darin, zu sehen, ob es eine integrierte API gab, um jegliche Netzwerkkommunikation zu vermeiden, oder sogar einen "abschaltenden Netzwerkzugriffsmechanismus", um z. B. kein Modul zu importieren, das Netzwerkkommunikation durchführen würde. Der Grund ist, dass vertrauliche Daten nicht undicht werden. Ihre Antwort bietet eine Möglichkeit, mit lokalen Links arbeiten zu können, was zwar wertvoll ist, aber keine Garantie bietet. – PonyEars

0

Selbst eine einfache import plotly bereits versucht, das Netzwerk als diesem Beispiel anschließen zeigt:

import logging 
logging.basicConfig(level=logging.INFO) 
import plotly 

Die Ausgabe lautet:

INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): api.plot.ly 

die Verbindung hergestellt wird, wenn die get_graph_reference() functionwhile the graph_reference module is initialized genannt wird.

Eine Möglichkeit, die Verbindung zu plot.ly-Servern zu vermeiden, besteht darin, plotly_api_domain in ~/.plotly/.config als ungültig zu definieren. Für mich ist dies keine Option, da die Software auf dem Clientcomputer ausgeführt wird und ich ihre Konfigurationsdatei nicht ändern möchte. Zusätzlich it is also not yet possible to change the configuration directory through an environment variable.

Ein Work-around ist auf Affen-Patch requests.get vor plotly importieren:

import requests 
import inspect 
original_get = requests.get 

def plotly_no_get(*args, **kwargs): 
    one_frame_up = inspect.stack()[1] 
    if one_frame_up[3] == 'get_graph_reference': 
     raise requests.exceptions.RequestException 
    return original_get(*args, **kwargs) 

requests.get = plotly_no_get 
import plotly 

Dies ist sicherlich keine vollständige Lösung, aber, wenn nichts anderes, dies zeigt, dass plot.ly derzeit nicht sein komplett offline laufen

0

Ich habe keine umfangreiche Tests durchgeführt, aber es sieht aus wie Plot.ly einen "Offline" -Modus bietet:

https://plot.ly/python/offline/

Ein einfaches Beispiel:

from plotly.offline import plot 
from plotly.graph_objs import Scatter 

plot([Scatter(x=[1, 2, 3], y=[3, 1, 6])]) 

Sie installieren können Handlung.ly über pip und dann das Skript ausführen eine statische HTML-Datei zu erzeugen:

$ pip install plotly 
$ python ./above_script.py 

Wenn ich laufen diese vom Terminal mein Web-Browser öffnet sich in der folgenden Datei URL:

file:///some/path/to/temp-plot.html 

Dies macht eine interact Grafik, die vollständig lokal zu Ihrem Dateisystem ist.