[racket] Plot woes

From: Neil Toronto (neil.toronto at gmail.com)
Date: Tue May 22 08:05:31 EDT 2012

I've replied to the list because this might be useful for other people.

On 05/22/2012 02:41 AM, Jens Axel Søgaard wrote:
> Hi Neil,
>
> I am attempting to draw 1/x in using plot.
> Ideally I'd like to be able to write:
>
>    (lambda (x) (if (zero? x) #f (/ x))
>
> in order to plot a function with singularities.

I've thought of such things before. Unfortunately, plot doesn't know 
where any singularities are, so it can't specifically sample the 
function at those points. I could probably allow the user to tell plot 
where they are, but I can't think of a good API for it. I'd want 
something general enough to handle 1D, 2D and 3D functions, which allows 
the user to specify countably many missing values, and direction of 
(dis)continuity.

> Since the contract for plot requires I must use numbers,
> I attempted to split the domain in two from -1 to -epsilon
> and from +epsilon to 1.
>
> That trick didn't work (see attached image).
>
> Am I missing something?

You're not missing anything. There's currently a problem with the 
renderers returned by `function', `surface3d' and others: they sample 
functions on the entire plotted domain, not just within the functions' 
stated domains. To split a function in half and not have it draw a line 
between the halves, you currently have to do something like this:

(plot (list (function (λ (x) (if (x . < . 0) (/ x) +nan.0)) -2 0)
             (function (λ (x) (if (x . > . 0) (/ x) +nan.0)) 0 2)))

This also causes performance problems when there are many small function 
renderers. Fixing it is next on my to-do list.

> Apropos something completely different:
>
> At the page "Introduction" it would be nice if
> the first example included (require plot).
>
> http://docs.racket-lang.org/plot/intro.html?q=plot

Duly noted.

Neil ⊥

Posted on the users mailing list.