web-dev-qa-db-fra.com

Incorporation d'un graphique Plotly dans un modèle Django

J'essaie d'incorporer un graphique circulaire compliqué dans un Django modèle html. Cela fonctionne très bien lorsque le graphique est produit en "mode en ligne" (c'est-à-dire que l'extrait html est stocké sur le serveur complot)) mais pas en "mode hors ligne" (c'est-à-dire lorsque le html est stocké localement). Dans ce dernier cas, le graphique n'apparaît pas. Je veux pouvoir stocker le html sur mon serveur local et intégrer les tracés à partir de là.

Voici le morceau qui fonctionne:

import plotly.plotly as py
import plotly.graph_objs as go
labels = [1,2,3,4]
values = [10,20,30,40]
ndata = 100
fig = {
    'data': [{'labels': labels,
          'values': values,
          'type': 'pie',
          'textposition':"none",
          'textinfo':"percent",
          'textfont':{'size':'12'},
          'showlegend':'false'}],
    'layout': {'title': 'Total:'+str(ndata),
           'showlegend':'false',
           'height':'200',
           'width':'200',
           'autosize':'false',
           'margin':{'t':'50','l':'75','r':'0','b':'10'},
           'separators':'.,'}
}
plotly_url = py.plot(fig, filename='myfile', auto_open=False)
pie_url = '<iframe width="200" height="200" frameborder="0" seamless="seamless" scrolling="no" src='+plotly_url+'.embed?width=200&height=200&link=false&showlegend=false></iframe>'

Notez que pie_url est passé sous forme de chaîne dans la requête de rendu Http dans Django. Le modèle interprète la chaîne en html en utilisant la balise safe, c'est-à-dire {{pie_url | safe}}.

Voici le morceau qui ne fonctionne pas:

from plotly.offline import download_plotlyjs, plot
import plotly.graph_objs as go
labels = [1,2,3,4]
values = [10,20,30,40]
ndata = 100
fig = {
    'data': [{'labels': labels,
          'values': values,
          'type': 'pie',
          'textposition':"none",
          'textinfo':"percent",
          'textfont':{'size':'12'},
          'showlegend':'false'}],
    'layout': {'title': 'Total:'+str(ndata),
           'showlegend':'false',
           'height':'200',
           'width':'200',
           'autosize':'false',
           'margin':{'t':'50','l':'75','r':'0','b':'10'},
           'separators':'.,'}
}
plotly_url = plot(fig, filename='file:///home/website/pie.html', auto_open=False)
pie_url = '''<iframe width="200" height="200" frameborder="0" seamless="seamless" scrolling="no" src=\"'''+plotly_url+'''.embed?width=200&height=200&link=false&showlegend=false\"></iframe>'''

Tout avis sera le bienvenu.

19
Hooloovoo

Au lieu d'écrire le html dans un fichier, vous pouvez avoir de manière schématique renvoyer la partie html du graphique sous forme de chaîne. Par exemple, en utilisant un TemplateView basé sur une classe:

import plotly.offline as opy
import plotly.graph_objs as go

class Graph(TemplateView):
    template_name = 'graph.html'

    def get_context_data(self, **kwargs):
        context = super(Graph, self).get_context_data(**kwargs)

        x = [-2,0,4,6,7]
        y = [q**2-q+3 for q in x]
        trace1 = go.Scatter(x=x, y=y, marker={'color': 'red', 'symbol': 104, 'size': "10"},
                            mode="lines",  name='1st Trace')

        data=go.Data([trace1])
        layout=go.Layout(title="Meine Daten", xaxis={'title':'x1'}, yaxis={'title':'x2'})
        figure=go.Figure(data=data,layout=layout)
        div = opy.plot(figure, auto_open=False, output_type='div')

        context['graph'] = div

        return context

et le modèle:

{% if graph %}
<div style="width:600;height:500">
{{ graph|safe }}
</div>
{% endif %}
35
Christian K.