[Django]-Embedding a Plotly chart in a Django template

56👍

Instead of writing the html to a file you can have plotly return the html part of the graph as a string. For example, using a class based TemplateView:

EDIT: Update for using recent (as of 2021/08) versions of plotly. The template does not need any changes.

import plotly.graph_objects 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')

        layout=go.Layout(title="Meine Daten", xaxis={'title':'x1'}, yaxis={'title':'x2'})
        figure=go.Figure(data=['trace1'],layout=layout)

        context['graph'] = figure.to_html()

        return context

This is the original code:

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

and the template:

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

33👍

There’s been a couple of updates to plotly, some of which are applicable here for plotly 4+:

  • Plotly is offline by default now

    Note: No internet connection, account, or payment is required to use plotly.py. Prior to version 4, this library could operate in either an “online” or “offline” mode. The documentation tended to emphasize the online mode, where graphs get published to the Chart Studio web service. In version 4, all “online” functionality was removed from the plotly package and is now available as the separate, optional, chart-studio package (See below). plotly.py version 4 is “offline” only, and does not include any functionality for uploading figures or data to cloud services.

  • Figures now have a to_html function

This allows you to do the following to embed a graph offline:

graph = fig.to_html(full_html=False, default_height=500, default_width=700)
context = {'graph': graph}
response = render(request, 'graph.html', context)

And in graph.html you can do:

{% if graph %}
{{ graph|safe }}
{% else %}
<p>No graph was provided.</p>
{% endif %}

2👍

Let’s suppose that your piece of code that draws the graph, i.e.

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>'''

is a funtion named graph_function(). Inside that one, just substitute

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>'''

with

plt_div = plotly.offline.plot(fig, output_type='div')

return plt_div

then in your views.py:

def graph_view(request):
    my_graph=graph_function()
    context={'graph':my_graph}
    return render(request, 'my_template.html', context_dict)

and then in your template:

{% if graph %}
{{ graph|safe }}
{% else %}
<p>No graph was provided.</p>
{% endif %}
👤Tms91

Leave a comment