Using matplotlib with Django Generic views

2019-04-02 03:15发布

问题:

I am trying to write a detailed page for each row of data in the table. I would like to generate a matplotlib graph dynamically for each page using the data from each row.

I have tried the code with a normal view and it works. However, when used with the detail_view page the image appears as a broken link. What should I include in the DetailView class to generate the graph for each page?

graph.py:

def plotResults(request):
    p=get_object_or_404(Read_alignment,pk=id)
    x =[]
    y=[]
    x.append(p.start)
    x.append(p.stop)
    y.append(p.count)
    y.append(p.count)
    fig=plt.figure()
    ax= fig.add_subplot(311)
    ax.set_xlim(right=30)
    ax.step(x,y,'-',where='post', label='post')
    canvas = FigureCanvas(fig)
    response= HttpResponse(mimetype='image/png')
    canvas.print_png(response)
    return response

url.py:

url(r'^(?P<pk>\d+)/align/plotResults.png$',plotResults),
url(r'^(?P<pk>\d+)/align/$',AlignDetailView.as_view(), name='AlignDetailView'),

views.py:

class AlignDetailView(DetailView):
    model = Read_alignment

    def get_queryset(self):
        queryset= Read_alignment.objects.filter(chr__icontains=3l)
        return queryset

    def get_context_data(self, **kwargs):
        context = super(AlignDetailView,self).get_context_data(**kwargs)
        context['alignment'] = self.object
        return context

How should I link the graph to the template preferably without static or media tags? Is it possible to generate the graphs without saving the PNG images to the static folder?

回答1:

There are two ways to do this depending on what you want to do.

  1. If you just want an image to be shown without any HTML, then just use a normal function view rand return a HttpResponse or if you really, really really want to use class based views override the get method and return a HttpResponse.

  2. If you want to show an HTML page with the image embedded somewhere in it. Then you can do two things

    1. Create a separate view that will respond with just the image as you did in your example, and in your HTML page just add <img src="path to that view url" />.

    2. Or if you don't want a separate view for the image then you have to create an image in the DetailView, save it to byte stream, base64 encode it and return it in your context as (for example) image. Then in your template you create an image tag with the base64 encoded data using <img src="data:image/png;base64,{{ image }}"/>.



回答2:

There is a nice example here.

http://wiki.scipy.org/Cookbook/Matplotlib/Django