[racket] plot request/patch: independent control of y axis in density plots

From: John Clements (clements at brinckerhoff.org)
Date: Wed Feb 29 19:15:00 EST 2012

Plot's new "density" function is awesome. I'd like to add something to it, though; independent control of the y axis. 

Here's the motivating scenario; I'm looking at server logs, to try to see which users are hammering the handin server hardest. Suppose I take a list of numbers representing the seconds on which a submission occurred.  I can plot the density of these using (density …), but what I get is the relative density, rather than the absolute density. In this case, I want the y axis to have the units "elements per unit time". This is different from an application such as the one in the docs where the number of data points is irrelevant. 

This problem becomes much more acute when I'm trying to compare two different sets of server logs; the current behavior essentially normalizes w.r.t. the number of points.

The easiest way to fix this is just to allow the user to have independent control over the y scaling, so that you can for instance write:

(plot (density all-seconds 0.0625
               #:y-adjust (/ 1 (length all-seconds)))
      #:width 800)

to get a graph that shows density in hits per second.

I've implemented this; the patch appears below.

Is there a simpler way to make this happen?

John




pcp073948pcs:~/plt/collects/plot/plot2d clements$ git diff line.rkt
diff --git a/collects/plot/plot2d/line.rkt b/collects/plot/plot2d/line.rkt
index 980ebde..43590b3 100644
--- a/collects/plot/plot2d/line.rkt
+++ b/collects/plot/plot2d/line.rkt
@@ -136,6 +136,7 @@
 ;; Kernel density estimation
 
 (defproc (density [xs (listof real?)] [bw-adjust real? 1]
+                  [#:y-adjust y-adjust real? 1]
                   [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f]
                   [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f]
                   [#:samples samples (and/c exact-integer? (>=/c 2)) (line-samples)]
@@ -149,7 +150,8 @@
   (define sd (sqrt (- (/ (sum sqr xs) n) (sqr (/ (sum values xs) n)))))
   (define h (* bw-adjust 1.06 sd (expt n -0.2)))
   (define-values (f fx-min fx-max) (kde xs h))
+  (define (scaled-f x) (* y-adjust (f x)))
   (let ([x-min  (if x-min x-min fx-min)]
         [x-max  (if x-max x-max fx-max)])
-    (function f x-min x-max #:y-min y-min #:y-max y-max #:samples samples
+    (function scaled-f x-min x-max #:y-min y-min #:y-max y-max #:samples samples
               #:color color #:width width #:style style #:alpha alpha #:label label)))

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4624 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20120229/d777505e/attachment.p7s>

Posted on the users mailing list.