2016-07-29 9 views
1

Ich möchte ein dynamisch generiertes Bild in meinem Haus hinzufügen. Ich möchte die Figur nicht speichern, sondern sie einfach nach einigem Text direkt auf meiner Homepage anzeigen. Mein views.py wie folgt aussieht:Fügen Sie eine dynamisch generierte Matplotlib Bild in Django zu Hause

from django.shortcuts import render 
def index(request): 
    import random 
    import datetime 
    import django 
    import pylab 
    import PIL, PIL.Image 
    import io 

    from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas 
    from matplotlib.figure import Figure 
    from matplotlib.dates import DateFormatter 

    fig=Figure() 
    ax=fig.add_subplot(111) 
    x=[] 
    y=[] 
    now=datetime.datetime.now() 
    delta=datetime.timedelta(days=1) 
    for i in range(10): 
     x.append(now) 
     now+=delta 
     y.append(random.randint(0, 1000)) 

    ax.plot_date(x, y, '-') 
    ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d')) 
    fig.autofmt_xdate() 
    canvas = FigureCanvas(fig) 
    graphic1 =django.http.HttpResponse(content_type='image/png') 
    canvas.print_png(graphic1) 
    return render(request, 'personal/home.html',{'graphic':graphic1}) 

Funktion index bereits im urls.py enthalten ist. Kein Problem dort. Meine home.html sieht aus wie

{% extends "personal/header.html" %} 
{% block content %} 
<p> Welcome to my website!</p> 
{% include "personal/includes/htmlpic.html" %} 
{% endblock %} 

Mein htmlpic.html ist:

{% block graphic %} 
<div id="content"> 
    <img src= "data:image/png;base64,{{graphic|safe}}" > 
</div> 
{% endblock %} 

Der Fehler: die Figur nicht zu sehen. Es ist ein Link wie folgt aus:

<img src="data:image/png;base64,&lt;HttpResponse status_code=200, " image png"> 

es klar kopiert den Status statt des Bildes in binären (und fügt ein zusätzliches Angebot). Kannst du mir sagen, was ich hier falsch mache? Oder schlagen Sie eine SO ähnliche Q & A vor?

PS. Ich bin ein Neuling in Django, bitte sei großzügig.

Antwort

2

In meiner Erfahrung, using data URIs is usually a bad idea.

In diesem Fall gibt es keinen wirklichen Bedarf für sie. Erstellen Sie einfach eine separate Ansicht, die das Bild zurückgibt. Ich verwende gnuplot hier zur Vereinfachung. Der Befehl druckt nur ein PNG-Bild einer Sinus-Funktion auf das Stdout. (Here sind einige Anweisungen auf dem Erhalten der Bilddaten von einer matplotlib Leinwand.) In views.py:

def my_plot(request): 
    import subprocess 
    plot = subprocess.check_output(['gnuplot', '-e', 'set terminal pngcairo; plot sin(x)']) 
    response = HttpResponse(plot, content_type="image/png") 
    return response 

Sagen Sie bitte diese Ansicht Karte plot url, damit die urls.py wie hier schreiben:

urlpatterns = patterns(
    '', 

    url(r'^$', views.index, name='home'), 

    url(r'^plot$', views.my_plot, name='plot') 
) 

Dann können Sie einfach die Ansicht verwenden, die das Bild als Quelle für Ihr Bild generiert. In htmlpic.html:

<img src="plot"></img> 

Für mich ist dies eine viel klarere Trennung von Bedenken. Eine Ansicht rendert Ihre Vorlage, die andere rendert das Bild. Wenn Sie dieses Bild an einer anderen Stelle in Ihrem Programm einbetten möchten, können Sie dies tun, ohne sich zu wiederholen.

+0

Danke für Ihre Antwort. Es scheint vielversprechend. Ich werde es später versuchen und es als gelöst markieren, wenn das für mich funktioniert. – giosans