diff --git a/gracedb/management/commands/make_histograms.py b/gracedb/management/commands/make_histograms.py
index 1a47e23b4bd88dfcee7372f4563da6b78c05776d..47014dc0362f83ce0bb72b5cf67be6c0de6f7f12 100644
--- a/gracedb/management/commands/make_histograms.py
+++ b/gracedb/management/commands/make_histograms.py
@@ -4,6 +4,10 @@ from django.core.management.base import BaseCommand, NoArgsCommand
 from django.db import connection
 from django.utils import dateformat
 
+import datetime
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plot
 
 from gracedb.gracedb.models import Event
 
@@ -13,18 +17,7 @@ from subprocess import Popen, PIPE, STDOUT
 
 
 DEST_DIR = "/tmp/foo"
-
-
-def analysisTypes():
-    cursor = connection.cursor()
-    cursor.execute("""
-        SELECT DISTINCT e.analysisType
-        FROM gracedb_event e, gracedb_group g
-        WHERE
-          (e.group_id <> g.id AND g.name = 'Test') AND
-          (e.analysisType <> 'HWINJ')
-        """)
-    return [x[0] for x in cursor.fetchall()]
+MAX_X = 1800
 
 
 class Command(NoArgsCommand):
@@ -38,7 +31,7 @@ class Command(NoArgsCommand):
         start_week = now - timedelta(7)
         start_month = now - timedelta(30)
 
-        PAST = 91
+        PAST = 110
         now -= timedelta(PAST)
         start_day -= timedelta(PAST)
         start_week -= timedelta(PAST)
@@ -46,22 +39,92 @@ class Command(NoArgsCommand):
 
         time_ranges =  [(start_day, "day"), (start_week, "week"), (start_month, "month")]
 
-        valid_types = analysisTypes()
+        annotations = {}
 
+        # Make the histograms, save as png's.
         for atype, atype_name in Event.ANALYSIS_TYPE_CHOICES:
-            if atype not in valid_types:
-                continue
+            annotations[atype] = {}
             for start_time, time_range in time_ranges:
-                try:
-                    label = "Latencies for %s Events" % atype_name
-                except KeyError:
-                    label = "Bad analysis type: %s" % atype
-                #labels = [label, "%s previous to %s" % (time_range, str(now))]
-                labels = [label, "%s previous to %s" % (time_range, dateformat.format(now, settings.DATE_FORMAT))]
-                d = histogramData(atype, start_time, now)
-                h = histogramImage(d, labels)
+                note = {}
+                fname = os.path.join(DEST_DIR, "%s-%s.png" % (atype, time_range))
+                note['fname'] = fname
+                data = Event.objects.filter(analysisType=atype,
+                                            created__range=[start_time, now],
+                                            gpstime__gt=0)
+                data = [e.reportingLatency() for e in data]
+                note['count'] = data.count()
+                data = [d for d in data if d <= MAX_X]
+                note['npoints'] = len(data)
+                note['over'] = note['count'] - note['npoints']
+                if note['npoints'] <= 0:
+                    try:
+                        os.unlink(fname)
+                    except OSError:
+                        pass
+                else:
+                    makePlot(data, atype, maxx=MAX_X).savefig(fname)
+                annotations[atype][time_range] = note
+
+
+def makePlot(data, title, maxx=1800, facecolor='green'):
+#   over = 0
+#   for d in data:
+#       if d > maxx:
+#           over += 1
+
+#   data = [d for d in data if d <= maxx]
+
+    nbins = maxx / 30
+    if not data:
+        data = [0]
+    n, bins, patches = plot.hist(data, nbins, facecolor=facecolor)
+
+    vmax = max(n)
+    if vmax <= 10:
+        vmax = 10
+    elif (vmax%10) == 0:
+        vmax += 10
+    else:
+        vmax += 10 - ((vmax) % 10)
+
+
+#   if over:
+#       plural = ""
+#       if over > 1:
+#           plural = "s"
+#       title += "\nNOTE: %d event%s > %d seconds" % (over, plural, maxx)
+
+    plot.xlabel('Seconds', fontsize=20)
+    plot.ylabel('Number of Events', fontsize=20)
+    plot.title(title)
+    plot.axis([0, maxx, 0, vmax])
+    plot.grid(True)
+
+    return plot
+
+
+
+#=================================================================
+# GNUPlot stuff.  Currently unused.
+#=================================================================
+
+# Usage:
+#   d = gnuplotHistogramData(atype, start_time, now)
+#   h = gnuplotHistogramImage(d, labels)
+#
+#   open(os.path.join(DEST_DIR,"%s-%s.png" % (atype, time_range)),"w").write(h)
+
+def analysisTypes():
+    cursor = connection.cursor()
+    cursor.execute("""
+        SELECT DISTINCT e.analysisType
+        FROM gracedb_event e, gracedb_group g
+        WHERE
+          (e.group_id <> g.id AND g.name = 'Test') AND
+          (e.analysisType <> 'HWINJ')
+        """)
+    return [x[0] for x in cursor.fetchall()]
 
-                open(os.path.join(DEST_DIR,"%s-%s.png" % (atype, time_range)),"w").write(h)
 
 #label = "Latencies for %s Events" % Event.getTypeLabel(atype)
 #   data = Event.objects.extra(select={"date":"DATE(created)"}) \
@@ -103,7 +166,7 @@ class GnuPlot(object):
         return self.p.stdout.read() # XXX ugh.  will it always read the whole thing?
 
 
-def histogramData(atype, start, end):
+def gnuplotHistogramData(atype, start, end):
     hist_data = {}
 
     data = Event.objects.filter(analysisType=atype,
@@ -120,7 +183,7 @@ def histogramData(atype, start, end):
     return hist_data
 
 
-def histogramImage(data, labels=[], size=(400,200)):
+def gnuplotHistogramImage(data, labels=[], size=(400,200)):
     if not data:
         data = { 0:0 }
     if isinstance(labels, str):
@@ -162,4 +225,3 @@ def histogramImage(data, labels=[], size=(400,200)):
     g = GnuPlot(plotCode)
     g.write_data(data)
     return g.get_image()
-