[racket] Plot: plot-new-window never happens?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Tue Apr 17 12:48:14 EDT 2012

All GUI activity like window drawing happens only in the main thread of
an eventspace. Your program also starts out in the main thread. So,
yes, drawing has to wait until your loop completes.

One solution is to put your loop in a separate thread. The example
below creates a thread and passes it to `yield' to wait until the
thread is done. The `yield' function is special in that it lets other
GUI activity happen while it waits:

 #lang at-exp racket
 (require plot
          racket/gui/base)
 (plot-new-window? #t)
 (yield
  (thread
   (lambda ()
     (let loop ()
       (let ((dummy (read)))
         (if (and (number? dummy) (zero? dummy))
             (void)
             (begin
               (plot (function (λ(x) (* x x)) -2 2))
               (loop))))))))

Although the above should work, it's not really a good idea to perform
GUI actions outside of the main thread. So, here's an improved version
that uses `queue-callback' to send the `plot' call back to the main
thread:

 #lang at-exp racket
 (require plot
          racket/gui/base)
 (plot-new-window? #t)
 (yield
  (thread
   (lambda ()
     (let loop ()
       (let ((dummy (read)))
         (if (and (number? dummy) (zero? dummy))
             (void)
             (begin
               ;; queue a callback instead of `plot' directly:
               (queue-callback
                (lambda ()
                  (plot (function (λ(x) (* x x)) -2 2))))
               (loop))))))))

For more information, see

 http://docs.racket-lang.org/gui/windowing-overview.html#(part._eventspaceinfo)


At Tue, 17 Apr 2012 10:40:55 -0400, Deren Dohoda wrote:
> I was messing around with a spline utility last night and was using
> the plot-new-window? setting to get a plot. The goal was to share an
> exe with a coworker who doesn't have Racket. Just a command-line app
> but to get the plot to display I needed a window and this seemed
> awesome. The problem is I couldn't get the plot to display when the
> thread was in a procedure. The window would appear but it was like the
> plot backend wasn't free to draw to it. Here's a way to reproduce it
> on v5.2:
> 
> #lang at-exp racket
> (require plot)
> (plot-new-window? #t)
> (let loop ()
>   (let ((dummy (read)))
>     (if (and (number? dummy) (zero? dummy))
>         (void)
>         (begin
>           (plot (function (λ(x) (* x x)) -2 2))
>           (loop)))))
> 
> So long as you are looping, new windows will appear without plot
> contents. When you finally quit (here by entering the number zero) all
> the plots are drawn in those windows. Any help? Did I do something
> horribly dumb?
> 
> Thanks,
> Deren
> 
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users


Posted on the users mailing list.