简体   繁体   中英

Simple Django Graph example using matplotlib

I'm looking for a very simple example of taking a Django QuerySet and then generating a graph using matplotlib. All the examples I've found have hard-coded data values or they don't really explain what they are doing. I thought this would be a good question for others as well.

Let me set the stage with a very simple example so this is very easy to follow for me and for other n00bs. ;-)

class Animals(models.Model):
    cats = models.PositiveSmallIntegerField
    dogs = models.PositiveSmallIntegerField
    created = created = models.DateTimeField(auto_now_add=True)

datatograph = Animals.objects.all()

How do I get datatograph into the right format so I can pass it to matplotlib and end up with two an X axis of integers, y axis of dates and a line for dogs and a line for cats.

Thank you!

First let's create some Animals objects (I removed the auto_now_add from your model to make this simpler):

from random import randint
from datetime import timedelta
from django.utils import timezone

from animals.models import Animals

animals = []
base_date = timezone.now().replace(day=1)
for i in range(0, 10):
    dt = base_date + timedelta(days=i)
    animals.append(Animals(
        cats=randint(0, 100),
        dogs=randint(0, 100),
        created=dt))

Animals.objects.bulk_create(animals)

Then we could do something like this:

from django.utils import timezone
from matplotlib import pyplot
from animals.models import Animals

# Fetch the data
begin_date = timezone.now().replace(
    day=1, hour=0, minute=0, second=0, microsecond=0)
end_date = begin_date.replace(day=11)
datatograph = Animals.objects.filter(
    created__gte=begin_date, created__lt=end_date
).values('cats', 'dogs', 'created')

# Transform the data
cats = list(map(lambda d: d['cats'], datatograph))
dogs = list(map(lambda d: d['dogs'], datatograph))
dates = list(map(lambda d: d['created'].day, datatograph))

# Set up the plots
cats_plot = pyplot.plot(dates, cats, 'bo-', label='Cats')[0]
dogs_plot = pyplot.plot(dates, dogs, 'ro-', label='Dogs')[0]

# Set up the axis
pyplot.axis([min(dates), max(dates), min(cats + dogs), max(cats + dogs)])
pyplot.xlabel('day')

# Set up the legend and title
pyplot.legend(handles=[cats_plot, dogs_plot])
pyplot.title('Animals')

# Show the plot
pyplot.show()

Which creates a chart like this .

I had a hard time understanding your answer because of the use of the lambda which I found a little hard to follow. I asked my friend to explain it and the secret sauce for my brain, was to know that what we're doing is converting each of the three columns in the ORM to an array (LIST in Python). I think this is a simpler answer for the beginner (like me).

class Animals(models.Model):
cats = models.PositiveSmallIntegerField
dogs = models.PositiveSmallIntegerField
created = created = models.DateTimeField(auto_now_add=True)

import matplotlib.pyplot as plt

datatograph = Animals.objects.all()

for a in datatograph
    catslist = catslist + [a.cats]
    dogslist = dogslist + [a.cats]
    dates = dates + [a.created]
plt.plot(dates, catslist)
plt.plot(dates, dogslist)
plt.show() # Pops up a dialog with the graph, se plt.savefig(filename.ext) to save in .ext format like .png
plt.close()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM