# HG changeset patch
# User William Stein <wstein@gmail.com>
# Date 1251004432 25200
# Node ID 2baaec83027ec87a519719d7f528df87938ee1e9
# Parent  fb791cdddfca91b9a373e598c97dfe865e6a74b5
trac 6811 -- prime_pi.plot is wrong

diff -r fb791cdddfca -r 2baaec83027e doc/en/reference/functions.rst
--- a/doc/en/reference/functions.rst	Wed Aug 19 22:32:37 2009 -0700
+++ b/doc/en/reference/functions.rst	Sat Aug 22 22:13:52 2009 -0700
@@ -12,3 +12,4 @@
    sage/functions/special
    sage/functions/wigner
    sage/functions/generalized
+   sage/functions/prime_pi
\ No newline at end of file
diff -r fb791cdddfca -r 2baaec83027e doc/en/reference/plotting.rst
--- a/doc/en/reference/plotting.rst	Wed Aug 19 22:32:37 2009 -0700
+++ b/doc/en/reference/plotting.rst	Sat Aug 22 22:13:52 2009 -0700
@@ -15,6 +15,7 @@
    sage/plot/density_plot
    sage/plot/disk
    sage/plot/line
+   sage/plot/step
    sage/plot/matrix_plot
    sage/plot/plot_field
    sage/plot/point
diff -r fb791cdddfca -r 2baaec83027e sage/functions/prime_pi.pyx
--- a/sage/functions/prime_pi.pyx	Wed Aug 19 22:32:37 2009 -0700
+++ b/sage/functions/prime_pi.pyx	Sat Aug 22 22:13:52 2009 -0700
@@ -5,7 +5,8 @@
     * R. Andrew Ohana
     * William Stein
 
-TESTS:
+TESTS::
+
     sage: z = sage.functions.prime_pi.PrimePi()
     sage: loads(dumps(z))
     Function that counts the number of primes up to x
@@ -70,7 +71,8 @@
     r"""
     Return the number of primes $\leq x$.
 
-    EXAMPLES:
+    EXAMPLES::
+    
         sage: prime_pi(7)
         4
         sage: prime_pi(100)
@@ -86,18 +88,20 @@
         sage: prime_pi(500509)
         41581
 	
-    The prime_pi function allows for use of additional memory. 
+    The prime_pi function allows for use of additional memory::
+    
         sage: prime_pi(500509, 8)
         41581
 
     The prime_pi function also has a special plotting method, so it plots
-    quickly and perfectly as a step function.
+    quickly and perfectly as a step function::
+    
         sage: P = plot(prime_pi, 50,100)
     """
-    
     def __repr__(self):
         """
-        EXAMPLES:
+        EXAMPLES::
+        
             sage: prime_pi.__repr__()
             'Function that counts the number of primes up to x'
         """
@@ -105,7 +109,8 @@
 
     def __cmp__(self, other):
         """
-        EXAMPLES:
+        EXAMPLES::
+        
             sage: P = sage.functions.prime_pi.PrimePi()
             sage: P == prime_pi
             True
@@ -158,8 +163,8 @@
             21151907950
             41203088796
 
-        We know this implementation is broken at least on some 32 bit 
-        systems for 2^46, so we are capping the maximum allowed value. 
+        We know this implementation is broken at least on some 32-bit 
+        systems for `2^{46}`, so we are capping the maximum allowed value.::
 
             sage: prime_pi(2^40+1)
             Traceback (most recent call last):
@@ -289,24 +294,30 @@
             prime = self.primes[position]
         return position
 
-    def plot(self, xmin=0, xmax=100, *args, **kwds):
+    def plot(self, xmin=0, xmax=100, vertical_lines=True, **kwds):
         """
-        EXAMPLES:
+        Draw a plot of the prime counting function from xmin to xmax.
+        All additional arguments are passed on to the line command.
+
+        WARNING: we draw the plot of prime_pi as a stairstep function
+        with explicitly drawn vertical lines where the function
+        jumps. Technically there should not be any vertical lines, but
+        they make the graph look much better, so we include them.
+        Use the option ``vertical_lines=False`` to turn these off. 
+        
+        EXAMPLES::
+        
             sage: plot(prime_pi, 1, 100)
+            sage: prime_pi.plot(-2,50,thickness=2, vertical_lines=False)
         """
-        primes = prime_range(xmin, xmax+2)
-        base = self(xmin)
-        if xmin <= 2:
-            v = [(xmin,0),(min(xmax,2),0)]
-            ymin = 0
-        else:
-            v = []
-            ymin = base
-        for i in range(len(primes)-1):
-            v.extend([(primes[i],base+i+1), (primes[i+1],base+i+1)])
-        P = sage.plot.all.line(v, *args, **kwds)
-        P.axes_range(xmin=xmin, xmax=xmax, ymin=ymin, ymax=base+len(primes))
-        return P
+        y = self(xmin)
+        v = [(xmin, y)]
+        for p in prime_range(xmin+1, xmax+1):
+            y += 1
+            v.append((p,y))
+        v.append((xmax,y))
+        from sage.plot.step import plot_step_function
+        return plot_step_function(v, vertical_lines=vertical_lines, **kwds)
 
 #############
 prime_pi = PrimePi()
diff -r fb791cdddfca -r 2baaec83027e sage/plot/all.py
--- a/sage/plot/all.py	Wed Aug 19 22:32:37 2009 -0700
+++ b/sage/plot/all.py	Sat Aug 22 22:13:52 2009 -0700
@@ -26,3 +26,5 @@
 from plot3d.tachyon import Tachyon
 
 from colors import Color, hue, rainbow
+
+from step import plot_step_function
diff -r fb791cdddfca -r 2baaec83027e sage/plot/step.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sage/plot/step.py	Sat Aug 22 22:13:52 2009 -0700
@@ -0,0 +1,63 @@
+"""
+Step function plots
+"""
+
+#*****************************************************************************
+#       Copyright (C) 2009 William Stein <wstein@gmail.com>,
+#
+#  Distributed under the terms of the GNU General Public License (GPL)
+#
+#    This code is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    General Public License for more details.
+#
+#  The full text of the GPL is available at:
+#
+#                  http://www.gnu.org/licenses/
+#*****************************************************************************
+
+def plot_step_function(v, vertical_lines=True, **kwds):
+    r"""
+    Return the line graphics object that gives the plot of the step
+    function `f` defined by the list `v` of pairs `(a,b)`.  Here if
+    `(a,b)` is in `v`, then `f(a) = b`.  The user does not have to
+    worry about sorting the input list `v`.
+
+    INPUT:
+
+        - `v` -- list of pairs (a,b)
+
+        - ``vertical_lines`` -- bool (default: True) if True, draw
+          vertical risers at each step of this step function.
+          Technically these vertical lines are not part of the graph
+          of this function, but they look very nice in the plot so we
+          include them by default
+
+    EXAMPLES::
+
+    We plot the prime counting function::
+
+        sage: plot_step_function([(i,prime_pi(i)) for i in range(20)])
+    
+        sage: plot_step_function([(i,sin(i)) for i in range(5,20)])
+
+    We pass in many options and get something that looks like "Space Invaders"::
+
+        sage: v = [(i,sin(i)) for i in range(5,20)]
+        sage: plot_step_function(v, vertical_lines=False, thickness=30, rgbcolor='purple', axes=False)
+    """
+    from plot import line
+    # make sorted copy of v (don't change in place, since that would be rude).
+    v = list(sorted(v))
+    if len(v) <= 1:
+        return line([]) # empty line
+    if vertical_lines:
+        w = []
+        for i in range(len(v)):
+            w.append(v[i])
+            if i+1 < len(v):
+                w.append((v[i+1][0],v[i][1]))
+        return line(w, **kwds)
+    else:
+        return sum(line([v[i],(v[i+1][0],v[i][1])], **kwds) for i in range(len(v)-1))
