Plot source reorg before separating "plot" into multiple packages

Also added plot/pict and plot/bitmap (and typed versions)
This commit is contained in:
Neil Toronto 2013-10-09 15:19:34 -06:00
parent 70b6f6464f
commit f6a4881347
142 changed files with 2046 additions and 1539 deletions

8
pkgs/plot/bitmap.rkt Normal file
View File

@ -0,0 +1,8 @@
#lang racket/base
(require unstable/latent-contract
"no-gui.rkt"
"private/no-gui/plot-bitmap.rkt")
(provide (all-from-out "no-gui.rkt")
(activate-contract-out plot plot3d))

View File

@ -1,199 +1,4 @@
#lang racket/base
;; A compatibility module for the old 'plot'.
(require racket/contract racket/class racket/snip racket/draw racket/vector
unstable/latent-contract unstable/latent-contract/defthing
;; Plotting
"common/math.rkt"
"common/contract.rkt"
"common/plot-element.rkt"
"plot2d/plot-area.rkt"
"plot3d/plot-area.rkt"
(prefix-in new. (only-in "main.rkt"
x-axis y-axis
plot-x-ticks plot-y-ticks plot-z-ticks
points error-bars vector-field
plot-title plot-x-label plot-y-label plot-z-label
plot-foreground plot-background
plot3d-angle plot3d-altitude))
"deprecated/renderers.rkt"
;; Miscellaneous
"deprecated/math.rkt")
(provide mix
(activate-contract-out plot-color?
plot plot3d
points vector-field error-bars
line
contour shade
surface)
(only-doc-out (all-defined-out))
;; Miscellaneous
make-vec derivative gradient)
(define (mix . data)
(for/fold ([f (λ (area) (void))]) ([d (in-list data)])
(λ (area)
(f area)
(d area)
(void))))
(defproc (plot-color? [v any/c]) boolean?
(and (member v '(white black yellow green aqua pink wheat gray brown blue violet cyan
turquoise magenta salmon red))
#t))
(define ((renderer2d->plot-data r) area)
((renderer2d-render-proc r) area)
(void))
(define ((renderer3d->plot-data r) area)
((renderer3d-render-proc r) area)
(void))
;; ===================================================================================================
;; Plotting
(define x-axis-data (renderer2d->plot-data (new.x-axis)))
(define y-axis-data (renderer2d->plot-data (new.y-axis)))
(defproc (plot [data ((is-a?/c 2d-plot-area%) . -> . void?)]
[#:width width real? 400] [#:height height real? 400]
[#:x-min x-min real? -5] [#:x-max x-max real? 5]
[#:y-min y-min real? -5] [#:y-max y-max real? 5]
[#:x-label x-label string? "X axis"] [#:y-label y-label string? "Y axis"]
[#:title title string? ""]
[#:fgcolor fgcolor (list/c byte? byte? byte?) '(0 0 0)]
[#:bgcolor bgcolor (list/c byte? byte? byte?) '(255 255 255)]
[#:lncolor lncolor (list/c byte? byte? byte?) '(255 0 0)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
) (is-a?/c image-snip%)
(define x-ticks ((new.plot-x-ticks) x-min x-max))
(define y-ticks ((new.plot-y-ticks) y-min y-max))
(define bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max)))
(parameterize ([new.plot-title title]
[new.plot-x-label x-label]
[new.plot-y-label y-label]
[new.plot-foreground fgcolor]
[new.plot-background bgcolor])
(define bm (make-bitmap (ceiling width) (ceiling height)))
(define dc (make-object bitmap-dc% bm))
(define area (make-object 2d-plot-area%
bounds-rect x-ticks x-ticks y-ticks y-ticks dc 0 0 width height))
(define data+axes (mix x-axis-data y-axis-data data))
(send area start-plot)
(send area start-renderer bounds-rect)
(data+axes area)
(send area end-renderers)
(send area end-plot)
(when out-file (send bm save-file out-file 'png))
(make-object image-snip% bm)))
(defproc (plot3d [data ((is-a?/c 3d-plot-area%) . -> . void?)]
[#:width width real? 400] [#:height height real? 400]
[#:x-min x-min real? -5] [#:x-max x-max real? 5]
[#:y-min y-min real? -5] [#:y-max y-max real? 5]
[#:z-min z-min real? -5] [#:z-max z-max real? 5]
[#:alt alt real? 30]
[#:az az real? 45]
[#:x-label x-label string? "X axis"]
[#:y-label y-label string? "Y axis"]
[#:z-label z-label string? "Z axis"]
[#:title title string? ""]
[#:fgcolor fgcolor (list/c byte? byte? byte?) '(0 0 0)]
[#:bgcolor bgcolor (list/c byte? byte? byte?) '(255 255 255)]
[#:lncolor lncolor (list/c byte? byte? byte?) '(255 0 0)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
) (is-a?/c image-snip%)
(define x-ticks ((new.plot-x-ticks) x-min x-max))
(define y-ticks ((new.plot-y-ticks) y-min y-max))
(define z-ticks ((new.plot-z-ticks) z-min z-max))
(define bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)))
(parameterize ([new.plot-title title]
[new.plot-x-label x-label]
[new.plot-y-label y-label]
[new.plot-z-label z-label]
[new.plot-foreground fgcolor]
[new.plot-background bgcolor]
[new.plot3d-angle az]
[new.plot3d-altitude alt])
(define bm (make-bitmap (ceiling width) (ceiling height)))
(define dc (make-object bitmap-dc% bm))
(define area (make-object 3d-plot-area%
bounds-rect x-ticks x-ticks y-ticks y-ticks z-ticks z-ticks dc 0 0 width height))
(send area start-plot)
(send area start-renderer bounds-rect)
(data area)
(send area end-renderers)
(send area end-plot)
(when out-file (send bm save-file out-file 'png))
(make-object image-snip% bm)))
;; ===================================================================================================
;; Functions that generate "plot data"
(defproc (points [vecs (listof (vectorof real?))]
[#:sym sym (or/c char? string? exact-integer? symbol?) 'square]
[#:color color plot-color? 'black]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (new.points (map (λ (v) (vector-take v 2)) vecs)
#:sym sym #:size 6 #:color color)))
(defproc (vector-field [f ((vector/c real? real?) . -> . (vector/c real? real?))]
[#:samples samples (and/c exact-integer? (>=/c 2)) 20]
[#:width width exact-positive-integer? 1]
[#:color color plot-color? 'red]
[#:style style (one-of/c 'scaled 'normalized 'real) 'scaled]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(define scale (case style
[(scaled) 'auto]
[(normalized) 'normalized]
[(real) 1.0]))
(renderer2d->plot-data
(new.vector-field f #:samples samples #:line-width width #:color color #:scale scale)))
(defproc (error-bars [vecs (listof (vector/c real? real? real?))]
[#:color color plot-color? 'black]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (new.error-bars vecs #:color color #:alpha 1 #:width 4)))
(defproc (line [f (real? . -> . (or/c real? (vector/c real? real?)))]
[#:samples samples (and/c exact-integer? (>=/c 2)) 150]
[#:width width (>=/c 0) 1]
[#:color color plot-color/c 'red]
[#:mode mode (one-of/c 'standard 'parametric) 'standard]
[#:mapping mapping (one-of/c 'cartesian 'polar) 'cartesian]
[#:t-min t-min real? -5] [#:t-max t-max real? 5]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (line-renderer f samples width color mode mapping t-min t-max)))
(defproc (contour [f (real? real? . -> . real?)]
[#:samples samples exact-nonnegative-integer? 50]
[#:width width (>=/c 0) 1]
[#:color color plot-color/c 'black]
[#:levels levels (or/c (and/c exact-integer? (>=/c 2)) (listof real?)) 10]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (contour-renderer f samples width color levels)))
(defproc (shade [f (real? real? . -> . real?)]
[#:samples samples (and/c exact-integer? (>=/c 2)) 50]
[#:levels levels (or/c (and/c exact-integer? (>=/c 2)) (listof real?)) 10]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (shade-renderer f samples levels)))
(defproc (surface [f (real? real? . -> . real?)]
[#:samples samples (and/c exact-integer? (>=/c 2)) 50]
[#:width width (>=/c 0) 1]
[#:color color plot-color/c 'black]
) ((is-a?/c 3d-plot-area%) . -> . void?)
(renderer3d->plot-data (surface-renderer f samples width color)))
(require "private/compat.rkt")
(provide (all-from-out "private/compat.rkt"))

View File

@ -1,88 +1,10 @@
#lang racket/base
(require racket/contract unstable/latent-contract)
(require unstable/latent-contract
"no-gui.rkt"
"private/gui/plot2d.rkt"
"private/gui/plot3d.rkt")
;; ===================================================================================================
;; General exports
(require "contracted/parameters.rkt")
(provide (all-from-out "contracted/parameters.rkt"))
(require "contracted/math.rkt")
(provide (struct-out ivl))
(require "contracted/axis-transform.rkt")
(provide (all-from-out "contracted/axis-transform.rkt"))
(require "contracted/ticks.rkt")
(provide (all-from-out "contracted/ticks.rkt"))
(require "contracted/date-time.rkt")
(provide (struct-out plot-time)
plot-time->seconds seconds->plot-time
datetime->real)
(require "common/nonrenderer.rkt")
(provide (activate-contract-out x-ticks y-ticks z-ticks invisible-rect invisible-rect3d))
;; ===================================================================================================
;; 2D exports
(require "plot2d/plot.rkt")
(provide (activate-contract-out plot/dc plot plot-bitmap plot-pict plot-snip plot-frame plot-file))
(require "plot2d/point.rkt")
(provide (activate-contract-out points vector-field error-bars))
(require "plot2d/line.rkt")
(provide (activate-contract-out lines parametric polar function inverse density))
(require "plot2d/interval.rkt")
(provide (activate-contract-out
lines-interval parametric-interval polar-interval function-interval inverse-interval))
(require "plot2d/contour.rkt")
(provide (activate-contract-out isoline contours contour-intervals))
(require "plot2d/rectangle.rkt")
(provide (activate-contract-out rectangles area-histogram discrete-histogram stacked-histogram))
(require "plot2d/decoration.rkt")
(provide (activate-contract-out
x-axis y-axis axes polar-axes
x-tick-lines y-tick-lines tick-grid
point-label parametric-label polar-label function-label inverse-label))
;; ===================================================================================================
;; 3D exports
(require "plot3d/plot.rkt")
(provide (activate-contract-out
plot3d/dc plot3d plot3d-bitmap plot3d-pict plot3d-snip plot3d-frame plot3d-file))
(require "plot3d/surface.rkt")
(provide (activate-contract-out surface3d))
(require "plot3d/contour.rkt")
(provide (activate-contract-out isoline3d contours3d contour-intervals3d))
(require "plot3d/line.rkt")
(provide (activate-contract-out lines3d parametric3d))
(require "plot3d/point.rkt")
(provide (activate-contract-out points3d vector-field3d))
(require "plot3d/isosurface.rkt")
(provide (activate-contract-out isosurface3d isosurfaces3d polar3d))
(require "plot3d/rectangle.rkt")
(provide (activate-contract-out rectangles3d discrete-histogram3d stacked-histogram3d))
(require "plot3d/decoration.rkt")
(provide (activate-contract-out point-label3d))
;; ===================================================================================================
;; Deprecated functions
(require "deprecated/deprecated.rkt")
(provide mix (activate-contract-out line contour shade surface))
(provide (all-from-out "no-gui.rkt")
(activate-contract-out plot-snip plot-frame plot)
(activate-contract-out plot3d-snip plot3d-frame plot3d))

87
pkgs/plot/no-gui.rkt Normal file
View File

@ -0,0 +1,87 @@
#lang racket/base
(require racket/contract unstable/latent-contract)
;; ===================================================================================================
;; General exports
(require "private/contracted/parameters.rkt")
(provide (all-from-out "private/contracted/parameters.rkt"))
(require "private/contracted/math.rkt")
(provide (struct-out ivl))
(require "private/contracted/axis-transform.rkt")
(provide (all-from-out "private/contracted/axis-transform.rkt"))
(require "private/contracted/ticks.rkt")
(provide (all-from-out "private/contracted/ticks.rkt"))
(require "private/contracted/date-time.rkt")
(provide (struct-out plot-time)
plot-time->seconds seconds->plot-time
datetime->real)
(require "private/common/nonrenderer.rkt")
(provide (activate-contract-out x-ticks y-ticks z-ticks invisible-rect invisible-rect3d))
;; ===================================================================================================
;; 2D exports
(require "private/no-gui/plot2d.rkt")
(provide (activate-contract-out plot/dc plot-bitmap plot-pict plot-file))
(require "private/plot2d/point.rkt")
(provide (activate-contract-out points vector-field error-bars))
(require "private/plot2d/line.rkt")
(provide (activate-contract-out lines parametric polar function inverse density))
(require "private/plot2d/interval.rkt")
(provide (activate-contract-out
lines-interval parametric-interval polar-interval function-interval inverse-interval))
(require "private/plot2d/contour.rkt")
(provide (activate-contract-out isoline contours contour-intervals))
(require "private/plot2d/rectangle.rkt")
(provide (activate-contract-out rectangles area-histogram discrete-histogram stacked-histogram))
(require "private/plot2d/decoration.rkt")
(provide (activate-contract-out
x-axis y-axis axes polar-axes
x-tick-lines y-tick-lines tick-grid
point-label parametric-label polar-label function-label inverse-label))
;; ===================================================================================================
;; 3D exports
(require "private/no-gui/plot3d.rkt")
(provide (activate-contract-out plot3d/dc plot3d-bitmap plot3d-pict plot3d-file))
(require "private/plot3d/surface.rkt")
(provide (activate-contract-out surface3d))
(require "private/plot3d/contour.rkt")
(provide (activate-contract-out isoline3d contours3d contour-intervals3d))
(require "private/plot3d/line.rkt")
(provide (activate-contract-out lines3d parametric3d))
(require "private/plot3d/point.rkt")
(provide (activate-contract-out points3d vector-field3d))
(require "private/plot3d/isosurface.rkt")
(provide (activate-contract-out isosurface3d isosurfaces3d polar3d))
(require "private/plot3d/rectangle.rkt")
(provide (activate-contract-out rectangles3d discrete-histogram3d stacked-histogram3d))
(require "private/plot3d/decoration.rkt")
(provide (activate-contract-out point-label3d))
;; ===================================================================================================
;; Deprecated functions
(require "private/deprecated/deprecated.rkt")
(provide mix (activate-contract-out line contour shade surface))

8
pkgs/plot/pict.rkt Normal file
View File

@ -0,0 +1,8 @@
#lang racket/base
(require unstable/latent-contract
"no-gui.rkt"
"private/no-gui/plot-pict.rkt")
(provide (all-from-out "no-gui.rkt")
(activate-contract-out plot plot3d))

View File

@ -1,307 +0,0 @@
#lang racket/base
;; Procedures that plot 2D renderers.
(require racket/draw racket/snip racket/contract racket/list racket/class racket/match
unstable/contract
pict
unstable/parameter-group
racket/lazy-require
unstable/latent-contract/defthing
"../common/contract.rkt"
"../common/math.rkt"
"../common/draw.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"../common/file-type.rkt"
"../common/deprecation-warning.rkt"
"../common/format.rkt"
"plot-area.rkt")
;; Require lazily: without this, Racket complains while generating documentation:
;; cannot instantiate `racket/gui/base' a second time in the same process
(lazy-require ["snip.rkt" (make-2d-plot-snip)]
["../common/gui.rkt" (make-snip-frame with-new-eventspace)])
(provide (except-out (all-defined-out) get-renderer-list get-bounds-rect get-ticks plot-dc))
;; ===================================================================================================
;; Plot to a given device context
(define (get-renderer-list renderer-tree)
(for/list ([r (flatten (list renderer-tree))])
(match r
[(nonrenderer bounds-rect bounds-fun ticks-fun)
(renderer2d bounds-rect bounds-fun ticks-fun #f)]
[_ r])))
(define (get-bounds-rect renderer-list x-min x-max y-min y-max)
(define given-bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max)))
(define plot-bounds-rect (bounds-fixpoint renderer-list given-bounds-rect))
(when (or (not (rect-rational? plot-bounds-rect))
(rect-zero-area? plot-bounds-rect))
(match-define (vector x-ivl y-ivl) plot-bounds-rect)
(error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a"
(ivl->plot-label x-ivl) (ivl->plot-label y-ivl)))
(rect-inexact->exact plot-bounds-rect))
(define (get-ticks renderer-list bounds-rect)
(define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks)
(for/lists (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks
) ([r (in-list renderer-list)])
(define ticks-fun (plot-element-ticks-fun r))
(cond [ticks-fun (ticks-fun bounds-rect)]
[else (values empty empty empty empty)])))
(values (remove-duplicates (append* all-x-ticks))
(remove-duplicates (append* all-x-far-ticks))
(remove-duplicates (append* all-y-ticks))
(remove-duplicates (append* all-y-far-ticks))))
(define (plot-dc renderer-list bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks
dc x y width height)
(define area (make-object 2d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks dc x y width height))
(send area start-plot)
(define legend-entries
(flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 2)))
(if render-proc (render-proc area) empty))))
(send area end-renderers)
(when (not (empty? legend-entries))
(send area draw-legend legend-entries))
(send area end-plot))
(defproc (plot/dc [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[dc (is-a?/c dc<%>)]
[x real?] [y real?] [width (>=/c 0)] [height (>=/c 0)]
[#: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]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks)
(get-ticks renderer-list bounds-rect))
(parameterize ([plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-legend-anchor legend-anchor])
(plot-dc renderer-list bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks
dc x y width height)))
;; ===================================================================================================
;; Plot to various other backends
;; Plot to a bitmap
(defproc (plot-bitmap [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c bitmap%)
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks)
(get-ticks renderer-list bounds-rect))
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(plot/dc renderer-tree dc 0 0 width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
width height))
(defproc (plot-pict [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) pict?
(define saved-values (plot-parameters))
(dc (λ (dc x y)
(parameterize/group
([plot-parameters saved-values])
(plot/dc renderer-tree dc x y width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)))
width height))
;; Plot to a snip
(defproc (plot-snip [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c image-snip%)
(parameterize ([plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-legend-anchor legend-anchor])
(define saved-plot-parameters (plot-parameters))
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max))
(define (make-bm anim? bounds-rect width height)
(define area #f)
(define bm
(parameterize/group ([plot-parameters saved-plot-parameters]
[plot-animating? (if anim? #t (plot-animating?))])
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks)
(get-ticks renderer-list bounds-rect))
(set! area (make-object 2d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks
dc 0 0 width height))
(send area start-plot)
(define legend-entries
(flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 2)))
(if render-proc (render-proc area) empty))))
(send area end-renderers)
(when (not (empty? legend-entries))
(send area draw-legend legend-entries))
(send area end-plot))
width height)))
(define (area-bounds->plot-bounds rect)
(match-define (vector (ivl area-x-min area-x-max) (ivl area-y-min area-y-max)) rect)
(match-define (vector x-min y-min) (send area dc->plot (vector area-x-min area-y-min)))
(match-define (vector x-max y-max) (send area dc->plot (vector area-x-max area-y-max)))
(vector (ivl x-min x-max) (ivl y-min y-max)))
(values bm (send area get-area-bounds-rect) area-bounds->plot-bounds))
(define-values (bm area-bounds-rect area-bounds->plot-bounds)
(make-bm #f bounds-rect width height))
(make-2d-plot-snip
bm saved-plot-parameters
make-bm bounds-rect area-bounds-rect area-bounds->plot-bounds width height)))
;; Plot to a frame
(defproc (plot-frame [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c object%)
(define snip
(plot-snip
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(make-snip-frame snip width height (if title (format "Plot: ~a" title) "Plot")))
;; Plot to a file
(defproc (plot-file [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define real-kind (if (eq? kind 'auto) (detect-image-file-type output) kind))
(case real-kind
[(png jpeg xbm xpm bmp)
(define bm
(plot-bitmap
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(send bm save-file output real-kind (plot-jpeg-quality))]
[(ps pdf svg)
(define dc
(case real-kind
[(ps) (new post-script-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[as-eps #t] [width width] [height height] [output output])]
[(pdf) (new pdf-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[width width] [height height] [output output])]
[(svg) (new svg-dc%
[width width] [height height] [output output] [exists 'truncate/replace])]))
(define-values (x-scale y-scale) (send dc get-device-scale))
(send dc start-doc "Rendering plot")
(send dc start-page)
(plot/dc renderer-tree dc 0 0
(inexact->exact (/ width x-scale)) (inexact->exact (/ height y-scale))
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)
(send dc end-page)
(send dc end-doc)])
(void))
;; Plot to a frame or a snip, depending on (plot-new-window?)
(defproc (plot [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:fgcolor fgcolor plot-color/c #f] [#:bgcolor bgcolor plot-color/c #f]
[#:lncolor lncolor plot-color/c #f] ; unused
) (or/c (is-a?/c snip%) void?)
(when fgcolor
(deprecation-warning "the plot #:fgcolor keyword argument" "plot-foreground"))
(when bgcolor
(deprecation-warning "the plot #:bgcolor keyword argument" "plot-background"))
(when lncolor
(deprecation-warning "the plot #:lncolor keyword argument"))
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(parameterize ([plot-foreground (if fgcolor fgcolor (plot-foreground))]
[plot-background (if bgcolor bgcolor (plot-background))])
(when out-file
(call plot-file out-file out-kind))
(cond [(plot-new-window?) (define frame (with-new-eventspace (λ () (call plot-frame))))
(send frame show #t)
(void)]
[else (call plot-snip)])))

View File

@ -1,352 +0,0 @@
#lang racket/base
;; Procedures that plot 3D renderers.
(require racket/draw racket/snip racket/match racket/list racket/class racket/contract
unstable/contract
pict
unstable/parameter-group
racket/lazy-require
unstable/latent-contract/defthing
"../common/contract.rkt"
"../common/math.rkt"
"../common/draw.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"../common/file-type.rkt"
"../common/deprecation-warning.rkt"
"../common/format.rkt"
"plot-area.rkt")
;; Require lazily: without this, Racket complains while generating documentation:
;; cannot instantiate `racket/gui/base' a second time in the same process
(lazy-require ["snip.rkt" (make-3d-plot-snip)]
["../common/gui.rkt" (make-snip-frame with-new-eventspace)])
(provide (except-out (all-defined-out) get-renderer-list get-bounds-rect get-ticks plot3d-dc))
;; ===================================================================================================
;; Plot to a given device context
(define (get-renderer-list renderer-tree)
(for/list ([r (flatten (list renderer-tree))])
(match r
[(nonrenderer bounds-rect bounds-fun ticks-fun)
(renderer3d bounds-rect bounds-fun ticks-fun #f)]
[_ r])))
(define (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max)
(define given-bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)))
(define plot-bounds-rect (bounds-fixpoint renderer-list given-bounds-rect))
(when (or (not (rect-rational? plot-bounds-rect))
(rect-zero-area? plot-bounds-rect))
(match-define (vector x-ivl y-ivl z-ivl) plot-bounds-rect)
(error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a, z ∈ ~a"
(ivl->plot-label x-ivl) (ivl->plot-label y-ivl) (ivl->plot-label z-ivl)))
(rect-inexact->exact plot-bounds-rect))
(define (get-ticks renderer-list bounds-rect)
(define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks all-z-ticks all-z-far-ticks)
(for/lists (all-x-ticks
all-x-far-ticks
all-y-ticks
all-y-far-ticks
all-z-ticks
all-z-far-ticks) ([r (in-list renderer-list)])
(define ticks-fun (plot-element-ticks-fun r))
(cond [ticks-fun (ticks-fun bounds-rect)]
[else (values empty empty empty empty empty empty)])))
(values (remove-duplicates (append* all-x-ticks))
(remove-duplicates (append* all-x-far-ticks))
(remove-duplicates (append* all-y-ticks))
(remove-duplicates (append* all-y-far-ticks))
(remove-duplicates (append* all-z-ticks))
(remove-duplicates (append* all-z-far-ticks))))
(define (plot3d-dc renderer-list bounds-rect
x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks
dc x y width height)
(define area (make-object 3d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks
dc x y width height))
(send area start-plot)
(define legend-entries
(flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 3)))
(if render-proc (render-proc area) empty))))
(send area end-renderers)
(when (not (empty? legend-entries))
(send area draw-legend legend-entries))
(send area end-plot))
(defproc (plot3d/dc [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[dc (is-a?/c dc<%>)]
[x real?] [y real?] [width (>=/c 0)] [height (>=/c 0)]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:angle angle real? (plot3d-angle)] [#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks)
(get-ticks renderer-list bounds-rect))
(parameterize ([plot3d-angle angle]
[plot3d-altitude altitude]
[plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-z-label z-label]
[plot-legend-anchor legend-anchor])
(plot3d-dc renderer-list bounds-rect
x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks
dc x y width height)))
;; ===================================================================================================
;; Plot to various other backends
;; Plot to a bitmap
(defproc (plot3d-bitmap [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c bitmap%)
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(plot3d/dc renderer-tree dc 0 0 width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:angle angle #:altitude altitude #:title title #:x-label x-label #:y-label y-label
#:z-label z-label #:legend-anchor legend-anchor))
width height))
(defproc (plot3d-pict [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) pict?
(define saved-plot-parameters (plot-parameters))
(dc (λ (dc x y)
(parameterize/group ([plot-parameters saved-plot-parameters])
(plot3d/dc renderer-tree dc x y width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min
#:z-max z-max #:angle angle #:altitude altitude #:title title #:x-label x-label
#:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)))
width height))
;; Plot to a snip
(defproc (plot3d-snip [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c image-snip%)
(parameterize ([plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-z-label z-label]
[plot-legend-anchor legend-anchor])
(define saved-plot-parameters (plot-parameters))
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks)
(get-ticks renderer-list bounds-rect))
(define render-list-hash (make-hash))
(define legend-entries-hash (make-hash))
(define (make-bm anim? angle altitude width height)
(parameterize/group ([plot-parameters saved-plot-parameters]
[plot-animating? (if anim? #t (plot-animating?))]
[plot3d-angle angle]
[plot3d-altitude altitude])
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(define area (make-object 3d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks
dc 0 0 width height))
(send area start-plot)
(cond [(not (hash-ref render-list-hash (plot-animating?) #f))
(hash-set!
legend-entries-hash (plot-animating?)
(flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 3)))
(if render-proc (render-proc area) empty))))
(hash-set! render-list-hash (plot-animating?) (send area get-render-list))]
[else
(send area put-render-list (hash-ref render-list-hash (plot-animating?)))])
(send area end-renderers)
(define legend-entries (hash-ref legend-entries-hash (plot-animating?) #f))
(when (not (empty? legend-entries))
(send area draw-legend legend-entries))
(send area end-plot))
width height)))
(make-3d-plot-snip
(make-bm #f angle altitude width height) saved-plot-parameters
make-bm angle altitude width height)))
;; Plot to a frame
(defproc (plot3d-frame [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c object%)
(define snip
(plot3d-snip
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:angle angle #:altitude altitude #:title title
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(make-snip-frame snip width height (if title (format "Plot: ~a" title) "Plot")))
;; Plot to any supported kind of file
(defproc (plot3d-file [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define real-kind (if (eq? kind 'auto) (detect-image-file-type output) kind))
(case real-kind
[(png jpeg xbm xpm bmp)
(define bm
(plot3d-bitmap
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:angle angle #:altitude altitude #:title title
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(send bm save-file output real-kind (plot-jpeg-quality))]
[(ps pdf svg)
(define dc
(case real-kind
[(ps) (new post-script-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[as-eps #t] [width width] [height height] [output output])]
[(pdf) (new pdf-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[width width] [height height] [output output])]
[(svg) (new svg-dc%
[width width] [height height] [output output] [exists 'truncate/replace])]))
(define-values (x-scale y-scale) (send dc get-device-scale))
(send dc start-doc "Rendering plot")
(send dc start-page)
(plot3d/dc renderer-tree dc 0 0
(inexact->exact (/ width x-scale)) (inexact->exact (/ height y-scale))
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:angle angle #:altitude altitude #:title title #:x-label x-label #:y-label y-label
#:z-label z-label #:legend-anchor legend-anchor)
(send dc end-page)
(send dc end-doc)])
(void))
;; Plot to a frame or a snip, depending on the value of plot-new-window?
(defproc (plot3d [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? #f] [#:altitude altitude real? #f]
[#:az az real? #f] [#:alt alt real? #f] ; backward-compatible aliases
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:fgcolor fgcolor plot-color/c #f] [#:bgcolor bgcolor plot-color/c #f]
[#:lncolor lncolor plot-color/c #f] ; unused
) (or/c (is-a?/c snip%) void?)
(when fgcolor
(deprecation-warning "the plot3d #:fgcolor keyword argument" "plot-foreground"))
(when bgcolor
(deprecation-warning "the plot3d #:bgcolor keyword argument" "plot-background"))
(when lncolor
(deprecation-warning "the plot3d #:lncolor keyword argument"))
(when az
(deprecation-warning "the plot3d #:az keyword argument" "#:angle"))
(when alt
(deprecation-warning "the plot3d #:alt keyword argument" "#:altitude"))
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:title title
#:angle (or angle az (plot3d-angle)) #:altitude (or altitude alt (plot3d-altitude))
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(parameterize ([plot-foreground (if fgcolor fgcolor (plot-foreground))]
[plot-background (if bgcolor bgcolor (plot-background))])
(when out-file
(call plot3d-file out-file out-kind))
(cond [(plot-new-window?) (define frame (with-new-eventspace (λ () (call plot3d-frame))))
(send frame show #t)
(void)]
[else (call plot3d-snip)])))

View File

@ -0,0 +1,199 @@
#lang racket/base
;; A compatibility module for the old 'plot'.
(require racket/contract racket/class racket/snip racket/draw racket/vector
unstable/latent-contract unstable/latent-contract/defthing
;; Plotting
"common/math.rkt"
"common/contract.rkt"
"common/plot-element.rkt"
"plot2d/plot-area.rkt"
"plot3d/plot-area.rkt"
(prefix-in new. (only-in plot
x-axis y-axis
plot-x-ticks plot-y-ticks plot-z-ticks
points error-bars vector-field
plot-title plot-x-label plot-y-label plot-z-label
plot-foreground plot-background
plot3d-angle plot3d-altitude))
"deprecated/renderers.rkt"
;; Miscellaneous
"deprecated/math.rkt")
(provide mix
(activate-contract-out plot-color?
plot plot3d
points vector-field error-bars
line
contour shade
surface)
(only-doc-out (all-defined-out))
;; Miscellaneous
make-vec derivative gradient)
(define (mix . data)
(for/fold ([f (λ (area) (void))]) ([d (in-list data)])
(λ (area)
(f area)
(d area)
(void))))
(defproc (plot-color? [v any/c]) boolean?
(and (member v '(white black yellow green aqua pink wheat gray brown blue violet cyan
turquoise magenta salmon red))
#t))
(define ((renderer2d->plot-data r) area)
((renderer2d-render-proc r) area)
(void))
(define ((renderer3d->plot-data r) area)
((renderer3d-render-proc r) area)
(void))
;; ===================================================================================================
;; Plotting
(define x-axis-data (renderer2d->plot-data (new.x-axis)))
(define y-axis-data (renderer2d->plot-data (new.y-axis)))
(defproc (plot [data ((is-a?/c 2d-plot-area%) . -> . void?)]
[#:width width real? 400] [#:height height real? 400]
[#:x-min x-min real? -5] [#:x-max x-max real? 5]
[#:y-min y-min real? -5] [#:y-max y-max real? 5]
[#:x-label x-label string? "X axis"] [#:y-label y-label string? "Y axis"]
[#:title title string? ""]
[#:fgcolor fgcolor (list/c byte? byte? byte?) '(0 0 0)]
[#:bgcolor bgcolor (list/c byte? byte? byte?) '(255 255 255)]
[#:lncolor lncolor (list/c byte? byte? byte?) '(255 0 0)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
) (is-a?/c image-snip%)
(define x-ticks ((new.plot-x-ticks) x-min x-max))
(define y-ticks ((new.plot-y-ticks) y-min y-max))
(define bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max)))
(parameterize ([new.plot-title title]
[new.plot-x-label x-label]
[new.plot-y-label y-label]
[new.plot-foreground fgcolor]
[new.plot-background bgcolor])
(define bm (make-bitmap (ceiling width) (ceiling height)))
(define dc (make-object bitmap-dc% bm))
(define area (make-object 2d-plot-area%
bounds-rect x-ticks x-ticks y-ticks y-ticks dc 0 0 width height))
(define data+axes (mix x-axis-data y-axis-data data))
(send area start-plot)
(send area start-renderer bounds-rect)
(data+axes area)
(send area end-renderers)
(send area end-plot)
(when out-file (send bm save-file out-file 'png))
(make-object image-snip% bm)))
(defproc (plot3d [data ((is-a?/c 3d-plot-area%) . -> . void?)]
[#:width width real? 400] [#:height height real? 400]
[#:x-min x-min real? -5] [#:x-max x-max real? 5]
[#:y-min y-min real? -5] [#:y-max y-max real? 5]
[#:z-min z-min real? -5] [#:z-max z-max real? 5]
[#:alt alt real? 30]
[#:az az real? 45]
[#:x-label x-label string? "X axis"]
[#:y-label y-label string? "Y axis"]
[#:z-label z-label string? "Z axis"]
[#:title title string? ""]
[#:fgcolor fgcolor (list/c byte? byte? byte?) '(0 0 0)]
[#:bgcolor bgcolor (list/c byte? byte? byte?) '(255 255 255)]
[#:lncolor lncolor (list/c byte? byte? byte?) '(255 0 0)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
) (is-a?/c image-snip%)
(define x-ticks ((new.plot-x-ticks) x-min x-max))
(define y-ticks ((new.plot-y-ticks) y-min y-max))
(define z-ticks ((new.plot-z-ticks) z-min z-max))
(define bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)))
(parameterize ([new.plot-title title]
[new.plot-x-label x-label]
[new.plot-y-label y-label]
[new.plot-z-label z-label]
[new.plot-foreground fgcolor]
[new.plot-background bgcolor]
[new.plot3d-angle az]
[new.plot3d-altitude alt])
(define bm (make-bitmap (ceiling width) (ceiling height)))
(define dc (make-object bitmap-dc% bm))
(define area (make-object 3d-plot-area%
bounds-rect x-ticks x-ticks y-ticks y-ticks z-ticks z-ticks dc 0 0 width height))
(send area start-plot)
(send area start-renderer bounds-rect)
(data area)
(send area end-renderers)
(send area end-plot)
(when out-file (send bm save-file out-file 'png))
(make-object image-snip% bm)))
;; ===================================================================================================
;; Functions that generate "plot data"
(defproc (points [vecs (listof (vectorof real?))]
[#:sym sym (or/c char? string? exact-integer? symbol?) 'square]
[#:color color plot-color? 'black]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (new.points (map (λ (v) (vector-take v 2)) vecs)
#:sym sym #:size 6 #:color color)))
(defproc (vector-field [f ((vector/c real? real?) . -> . (vector/c real? real?))]
[#:samples samples (and/c exact-integer? (>=/c 2)) 20]
[#:width width exact-positive-integer? 1]
[#:color color plot-color? 'red]
[#:style style (one-of/c 'scaled 'normalized 'real) 'scaled]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(define scale (case style
[(scaled) 'auto]
[(normalized) 'normalized]
[(real) 1.0]))
(renderer2d->plot-data
(new.vector-field f #:samples samples #:line-width width #:color color #:scale scale)))
(defproc (error-bars [vecs (listof (vector/c real? real? real?))]
[#:color color plot-color? 'black]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (new.error-bars vecs #:color color #:alpha 1 #:width 4)))
(defproc (line [f (real? . -> . (or/c real? (vector/c real? real?)))]
[#:samples samples (and/c exact-integer? (>=/c 2)) 150]
[#:width width (>=/c 0) 1]
[#:color color plot-color/c 'red]
[#:mode mode (one-of/c 'standard 'parametric) 'standard]
[#:mapping mapping (one-of/c 'cartesian 'polar) 'cartesian]
[#:t-min t-min real? -5] [#:t-max t-max real? 5]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (line-renderer f samples width color mode mapping t-min t-max)))
(defproc (contour [f (real? real? . -> . real?)]
[#:samples samples exact-nonnegative-integer? 50]
[#:width width (>=/c 0) 1]
[#:color color plot-color/c 'black]
[#:levels levels (or/c (and/c exact-integer? (>=/c 2)) (listof real?)) 10]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (contour-renderer f samples width color levels)))
(defproc (shade [f (real? real? . -> . real?)]
[#:samples samples (and/c exact-integer? (>=/c 2)) 50]
[#:levels levels (or/c (and/c exact-integer? (>=/c 2)) (listof real?)) 10]
) ((is-a?/c 2d-plot-area%) . -> . void?)
(renderer2d->plot-data (shade-renderer f samples levels)))
(defproc (surface [f (real? real? . -> . real?)]
[#:samples samples (and/c exact-integer? (>=/c 2)) 50]
[#:width width (>=/c 0) 1]
[#:color color plot-color/c 'black]
) ((is-a?/c 3d-plot-area%) . -> . void?)
(renderer3d->plot-data (surface-renderer f samples width color)))

View File

@ -41,7 +41,8 @@
;; ===================================================================================================
;; 2D exports
(require "plot2d/plot.rkt"
(require "no-gui/plot2d.rkt"
"gui/plot2d.rkt"
"plot2d/point.rkt"
"plot2d/line.rkt"
"plot2d/interval.rkt"
@ -50,7 +51,8 @@
"plot2d/decoration.rkt")
(provide (only-doc-out
(combine-out (all-from-out "plot2d/plot.rkt")
(combine-out (all-from-out "no-gui/plot2d.rkt")
(all-from-out "gui/plot2d.rkt")
(all-from-out "plot2d/point.rkt")
(all-from-out "plot2d/line.rkt")
(all-from-out "plot2d/interval.rkt")
@ -61,7 +63,8 @@
;; ===================================================================================================
;; 3D exports
(require "plot3d/plot.rkt"
(require "no-gui/plot3d.rkt"
"gui/plot3d.rkt"
"plot3d/surface.rkt"
"plot3d/contour.rkt"
"plot3d/line.rkt"
@ -71,7 +74,8 @@
"plot3d/decoration.rkt")
(provide (only-doc-out
(combine-out (all-from-out "plot3d/plot.rkt")
(combine-out (all-from-out "no-gui/plot3d.rkt")
(all-from-out "gui/plot3d.rkt")
(all-from-out "plot3d/surface.rkt")
(all-from-out "plot3d/contour.rkt")
(all-from-out "plot3d/line.rkt")

View File

@ -0,0 +1,134 @@
#lang racket/base
(require racket/snip racket/contract racket/class racket/match
unstable/contract
unstable/parameter-group
racket/lazy-require
unstable/latent-contract/defthing
"../common/contract.rkt"
"../common/math.rkt"
"../common/draw.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"../common/deprecation-warning.rkt"
"../plot2d/plot-area.rkt"
"../no-gui/plot2d.rkt"
"../no-gui/plot2d-utils.rkt")
;; Require lazily, in case someone wants to just (require plot) in a headless setup
(lazy-require ["snip2d.rkt" (make-2d-plot-snip)]
["gui.rkt" (make-snip-frame with-new-eventspace)])
(provide plot-snip plot-frame plot)
;; ===================================================================================================
;; Plot to a snip
(defproc (plot-snip [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c image-snip%)
(parameterize ([plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-legend-anchor legend-anchor])
(define saved-plot-parameters (plot-parameters))
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max))
(define (make-bm anim? bounds-rect width height)
(define area #f)
(define bm
(parameterize/group ([plot-parameters saved-plot-parameters]
[plot-animating? (if anim? #t (plot-animating?))])
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks)
(get-ticks renderer-list bounds-rect))
(set! area (make-object 2d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks
dc 0 0 width height))
(plot-area area renderer-list))
width height)))
(define (area-bounds->plot-bounds rect)
(match-define (vector (ivl area-x-min area-x-max) (ivl area-y-min area-y-max)) rect)
(match-define (vector x-min y-min) (send area dc->plot (vector area-x-min area-y-min)))
(match-define (vector x-max y-max) (send area dc->plot (vector area-x-max area-y-max)))
(vector (ivl x-min x-max) (ivl y-min y-max)))
(values bm (send area get-area-bounds-rect) area-bounds->plot-bounds))
(define-values (bm area-bounds-rect area-bounds->plot-bounds)
(make-bm #f bounds-rect width height))
(make-2d-plot-snip
bm saved-plot-parameters
make-bm bounds-rect area-bounds-rect area-bounds->plot-bounds width height)))
;; ===================================================================================================
;; Plot to a frame
(defproc (plot-frame [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c object%)
(define snip
(plot-snip
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(make-snip-frame snip width height (if title (format "Plot: ~a" title) "Plot")))
;; ===================================================================================================
;; Plot to a frame or a snip, depending on (plot-new-window?)
(defproc (plot [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:fgcolor fgcolor plot-color/c #f] [#:bgcolor bgcolor plot-color/c #f]
[#:lncolor lncolor plot-color/c #f] ; unused
) (or/c (is-a?/c snip%) void?)
(when fgcolor
(deprecation-warning "the plot #:fgcolor keyword argument" "plot-foreground"))
(when bgcolor
(deprecation-warning "the plot #:bgcolor keyword argument" "plot-background"))
(when lncolor
(deprecation-warning "the plot #:lncolor keyword argument"))
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(parameterize ([plot-foreground (if fgcolor fgcolor (plot-foreground))]
[plot-background (if bgcolor bgcolor (plot-background))])
(when out-file
(call plot-file out-file out-kind))
(cond [(plot-new-window?) (define frame (with-new-eventspace (λ () (call plot-frame))))
(send frame show #t)
(void)]
[else (call plot-snip)])))

View File

@ -0,0 +1,166 @@
#lang racket/base
(require racket/snip racket/match racket/list racket/class racket/contract
unstable/contract
unstable/parameter-group
racket/lazy-require
unstable/latent-contract/defthing
"../common/contract.rkt"
"../common/math.rkt"
"../common/draw.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"../common/deprecation-warning.rkt"
"../plot3d/plot-area.rkt"
"../no-gui/plot3d.rkt"
"../no-gui/plot3d-utils.rkt")
;; Require lazily, in case someone wants to just (require plot) in a headless setup
(lazy-require ["snip3d.rkt" (make-3d-plot-snip)]
["gui.rkt" (make-snip-frame with-new-eventspace)])
(provide plot3d-snip plot3d-frame plot3d)
;; ===================================================================================================
;; Plot to a snip
(defproc (plot3d-snip [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c image-snip%)
(parameterize ([plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-z-label z-label]
[plot-legend-anchor legend-anchor])
(define saved-plot-parameters (plot-parameters))
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks)
(get-ticks renderer-list bounds-rect))
(define render-list-hash (make-hash))
(define legend-entries-hash (make-hash))
(define (make-bm anim? angle altitude width height)
(parameterize/group ([plot-parameters saved-plot-parameters]
[plot-animating? (if anim? #t (plot-animating?))]
[plot3d-angle angle]
[plot3d-altitude altitude])
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(define area (make-object 3d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks
dc 0 0 width height))
(send area start-plot)
(cond [(not (hash-ref render-list-hash (plot-animating?) #f))
(hash-set!
legend-entries-hash (plot-animating?)
(flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 3)))
(if render-proc (render-proc area) empty))))
(hash-set! render-list-hash (plot-animating?) (send area get-render-list))]
[else
(send area put-render-list (hash-ref render-list-hash (plot-animating?)))])
(send area end-renderers)
(define legend-entries (hash-ref legend-entries-hash (plot-animating?) #f))
(when (not (empty? legend-entries))
(send area draw-legend legend-entries))
(send area end-plot))
width height)))
(make-3d-plot-snip
(make-bm #f angle altitude width height) saved-plot-parameters
make-bm angle altitude width height)))
;; ===================================================================================================
;; Plot to a frame
(defproc (plot3d-frame [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c object%)
(define snip
(plot3d-snip
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:angle angle #:altitude altitude #:title title
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(make-snip-frame snip width height (if title (format "Plot: ~a" title) "Plot")))
;; ===================================================================================================
;; Plot to a frame or a snip, depending on the value of plot-new-window?
(defproc (plot3d [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? #f] [#:altitude altitude real? #f]
[#:az az real? #f] [#:alt alt real? #f] ; backward-compatible aliases
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:fgcolor fgcolor plot-color/c #f] [#:bgcolor bgcolor plot-color/c #f]
[#:lncolor lncolor plot-color/c #f] ; unused
) (or/c (is-a?/c snip%) void?)
(when fgcolor
(deprecation-warning "the plot3d #:fgcolor keyword argument" "plot-foreground"))
(when bgcolor
(deprecation-warning "the plot3d #:bgcolor keyword argument" "plot-background"))
(when lncolor
(deprecation-warning "the plot3d #:lncolor keyword argument"))
(when az
(deprecation-warning "the plot3d #:az keyword argument" "#:angle"))
(when alt
(deprecation-warning "the plot3d #:alt keyword argument" "#:altitude"))
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:title title
#:angle (or angle az (plot3d-angle)) #:altitude (or altitude alt (plot3d-altitude))
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(parameterize ([plot-foreground (if fgcolor fgcolor (plot-foreground))]
[plot-background (if bgcolor bgcolor (plot-background))])
(when out-file
(call plot3d-file out-file out-kind))
(cond [(plot-new-window?) (define frame (with-new-eventspace (λ () (call plot3d-frame))))
(send frame show #t)
(void)]
[else (call plot3d-snip)])))

View File

@ -1,10 +1,10 @@
#lang racket/base
(require racket/gui/base racket/class racket/list unstable/parameter-group
"math.rkt"
"parameters.rkt"
"plot-device.rkt"
"worker-thread.rkt")
"../common/math.rkt"
"../common/parameters.rkt"
"../common/plot-device.rkt"
"../common/worker-thread.rkt")
(provide plot-snip%)

View File

@ -1,7 +1,7 @@
#lang racket/base
(require racket/gui/base racket/class racket/match racket/list racket/math unstable/parameter-group
"../common/snip.rkt"
"snip.rkt"
"../common/plot-device.rkt"
"../common/math.rkt"
"../common/format.rkt"

View File

@ -1,7 +1,7 @@
#lang racket/base
(require racket/gui/base racket/class racket/match unstable/parameter-group
"../common/snip.rkt"
"snip.rkt"
"../common/math.rkt"
"../common/worker-thread.rkt"
"../common/parameters.rkt")

View File

@ -0,0 +1,63 @@
#lang racket/base
(require racket/contract
racket/class
unstable/latent-contract/defthing
unstable/contract
racket/draw
"../common/contract.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"plot2d.rkt"
"plot3d.rkt")
(provide (all-defined-out))
(defproc (plot [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) (is-a?/c bitmap%)
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(when out-file
(call plot-file out-file out-kind))
(call plot-bitmap))
(defproc (plot3d [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? #f] [#:altitude altitude real? #f]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) (is-a?/c bitmap%)
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:title title
#:angle (or angle (plot3d-angle)) #:altitude (or altitude (plot3d-altitude))
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(when out-file
(call plot3d-file out-file out-kind))
(call plot3d-bitmap))

View File

@ -0,0 +1,62 @@
#lang racket/base
(require racket/contract
unstable/latent-contract/defthing
unstable/contract
pict
"../common/contract.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"plot2d.rkt"
"plot3d.rkt")
(provide (all-defined-out))
(defproc (plot [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) pict?
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(when out-file
(call plot-file out-file out-kind))
(call plot-pict))
(defproc (plot3d [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? #f] [#:altitude altitude real? #f]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) pict?
(define (call f . args)
(apply f renderer-tree args
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:title title
#:angle (or angle (plot3d-angle)) #:altitude (or altitude (plot3d-altitude))
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(when out-file
(call plot3d-file out-file out-kind))
(call plot3d-pict))

View File

@ -0,0 +1,56 @@
#lang racket/base
(require racket/list racket/class racket/match
"../common/math.rkt"
"../common/plot-element.rkt"
"../common/format.rkt")
(provide (all-defined-out))
(define (get-renderer-list renderer-tree)
(for/list ([r (flatten (list renderer-tree))])
(match r
[(nonrenderer bounds-rect bounds-fun ticks-fun)
(renderer2d bounds-rect bounds-fun ticks-fun #f)]
[_ r])))
(define (get-bounds-rect renderer-list x-min x-max y-min y-max)
(define given-bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max)))
(define plot-bounds-rect (bounds-fixpoint renderer-list given-bounds-rect))
(when (or (not (rect-rational? plot-bounds-rect))
(rect-zero-area? plot-bounds-rect))
(match-define (vector x-ivl y-ivl) plot-bounds-rect)
(error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a"
(ivl->plot-label x-ivl) (ivl->plot-label y-ivl)))
(rect-inexact->exact plot-bounds-rect))
(define (get-ticks renderer-list bounds-rect)
(define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks)
(for/lists (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks
) ([r (in-list renderer-list)])
(define ticks-fun (plot-element-ticks-fun r))
(cond [ticks-fun (ticks-fun bounds-rect)]
[else (values empty empty empty empty)])))
(values (remove-duplicates (append* all-x-ticks))
(remove-duplicates (append* all-x-far-ticks))
(remove-duplicates (append* all-y-ticks))
(remove-duplicates (append* all-y-far-ticks))))
(define (plot-area area renderer-list)
(send area start-plot)
(define legend-entries
(flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 2)))
(if render-proc (render-proc area) empty))))
(send area end-renderers)
(when (not (empty? legend-entries))
(send area draw-legend legend-entries))
(send area end-plot))

View File

@ -0,0 +1,132 @@
#lang racket/base
(require racket/draw racket/contract racket/class
unstable/contract
pict
unstable/parameter-group
unstable/latent-contract/defthing
"../common/contract.rkt"
"../common/draw.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"../common/file-type.rkt"
"../plot2d/plot-area.rkt"
"plot2d-utils.rkt")
(provide (all-defined-out))
;; ===================================================================================================
;; Plot to a given device context
(defproc (plot/dc [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[dc (is-a?/c dc<%>)]
[x real?] [y real?] [width (>=/c 0)] [height (>=/c 0)]
[#: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]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks)
(get-ticks renderer-list bounds-rect))
(parameterize ([plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-legend-anchor legend-anchor])
(define area (make-object 2d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks dc x y width height))
(plot-area area renderer-list)))
;; ===================================================================================================
;; Plot to a bitmap
(defproc (plot-bitmap [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c bitmap%)
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks)
(get-ticks renderer-list bounds-rect))
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(plot/dc renderer-tree dc 0 0 width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
width height))
;; ===================================================================================================
;; Plot to a pict
(defproc (plot-pict [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) pict?
(define saved-values (plot-parameters))
(dc (λ (dc x y)
(parameterize/group
([plot-parameters saved-values])
(plot/dc renderer-tree dc x y width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)))
width height))
;; ===================================================================================================
;; Plot to a file
(defproc (plot-file [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define real-kind (if (eq? kind 'auto) (detect-image-file-type output) kind))
(case real-kind
[(png jpeg xbm xpm bmp)
(define bm
(plot-bitmap
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))
(send bm save-file output real-kind (plot-jpeg-quality))]
[(ps pdf svg)
(define dc
(case real-kind
[(ps) (new post-script-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[as-eps #t] [width width] [height height] [output output])]
[(pdf) (new pdf-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[width width] [height height] [output output])]
[(svg) (new svg-dc%
[width width] [height height] [output output] [exists 'truncate/replace])]))
(define-values (x-scale y-scale) (send dc get-device-scale))
(send dc start-doc "Rendering plot")
(send dc start-page)
(plot/dc renderer-tree dc 0 0
(inexact->exact (/ width x-scale)) (inexact->exact (/ height y-scale))
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max
#:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)
(send dc end-page)
(send dc end-doc)])
(void))

View File

@ -0,0 +1,61 @@
#lang racket/base
(require racket/match racket/list racket/class
"../common/math.rkt"
"../common/plot-element.rkt"
"../common/format.rkt")
(provide (all-defined-out))
(define (get-renderer-list renderer-tree)
(for/list ([r (flatten (list renderer-tree))])
(match r
[(nonrenderer bounds-rect bounds-fun ticks-fun)
(renderer3d bounds-rect bounds-fun ticks-fun #f)]
[_ r])))
(define (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max)
(define given-bounds-rect (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)))
(define plot-bounds-rect (bounds-fixpoint renderer-list given-bounds-rect))
(when (or (not (rect-rational? plot-bounds-rect))
(rect-zero-area? plot-bounds-rect))
(match-define (vector x-ivl y-ivl z-ivl) plot-bounds-rect)
(error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a, z ∈ ~a"
(ivl->plot-label x-ivl) (ivl->plot-label y-ivl) (ivl->plot-label z-ivl)))
(rect-inexact->exact plot-bounds-rect))
(define (get-ticks renderer-list bounds-rect)
(define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks all-z-ticks all-z-far-ticks)
(for/lists (all-x-ticks
all-x-far-ticks
all-y-ticks
all-y-far-ticks
all-z-ticks
all-z-far-ticks) ([r (in-list renderer-list)])
(define ticks-fun (plot-element-ticks-fun r))
(cond [ticks-fun (ticks-fun bounds-rect)]
[else (values empty empty empty empty empty empty)])))
(values (remove-duplicates (append* all-x-ticks))
(remove-duplicates (append* all-x-far-ticks))
(remove-duplicates (append* all-y-ticks))
(remove-duplicates (append* all-y-far-ticks))
(remove-duplicates (append* all-z-ticks))
(remove-duplicates (append* all-z-far-ticks))))
(define (plot-area area renderer-list)
(send area start-plot)
(define legend-entries
(flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 3)))
(if render-proc (render-proc area) empty))))
(send area end-renderers)
(when (not (empty? legend-entries))
(send area draw-legend legend-entries))
(send area end-plot))

View File

@ -0,0 +1,150 @@
#lang racket/base
(require racket/draw racket/class racket/contract
unstable/contract
pict
unstable/parameter-group
unstable/latent-contract/defthing
"../common/contract.rkt"
"../common/draw.rkt"
"../common/parameters.rkt"
"../common/plot-element.rkt"
"../common/file-type.rkt"
"../plot3d/plot-area.rkt"
"plot3d-utils.rkt")
(provide (all-defined-out))
;; ===================================================================================================
;; Plot to a given device context
(defproc (plot3d/dc [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[dc (is-a?/c dc<%>)]
[x real?] [y real?] [width (>=/c 0)] [height (>=/c 0)]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:angle angle real? (plot3d-angle)] [#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define renderer-list (get-renderer-list renderer-tree))
(define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max))
(define-values (x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks)
(get-ticks renderer-list bounds-rect))
(parameterize ([plot3d-angle angle]
[plot3d-altitude altitude]
[plot-title title]
[plot-x-label x-label]
[plot-y-label y-label]
[plot-z-label z-label]
[plot-legend-anchor legend-anchor])
(define area (make-object 3d-plot-area%
bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks
dc x y width height))
(plot-area area renderer-list)))
;; ===================================================================================================
;; Plot to a bitmap
(defproc (plot3d-bitmap [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) (is-a?/c bitmap%)
((if (plot-animating?) draw-bitmap draw-bitmap/supersampling)
(λ (dc)
(plot3d/dc renderer-tree dc 0 0 width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:angle angle #:altitude altitude #:title title #:x-label x-label #:y-label y-label
#:z-label z-label #:legend-anchor legend-anchor))
width height))
;; ===================================================================================================
;; Plot to a pict
(defproc (plot3d-pict [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
) pict?
(define saved-plot-parameters (plot-parameters))
(dc (λ (dc x y)
(parameterize/group ([plot-parameters saved-plot-parameters])
(plot3d/dc renderer-tree dc x y width height
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min
#:z-max z-max #:angle angle #:altitude altitude #:title title #:x-label x-label
#:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)))
width height))
;; ===================================================================================================
;; Plot to any supported kind of file
(defproc (plot3d-file [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]) void?
(define real-kind (if (eq? kind 'auto) (detect-image-file-type output) kind))
(case real-kind
[(png jpeg xbm xpm bmp)
(define bm
(plot3d-bitmap
renderer-tree
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:width width #:height height #:angle angle #:altitude altitude #:title title
#:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))
(send bm save-file output real-kind (plot-jpeg-quality))]
[(ps pdf svg)
(define dc
(case real-kind
[(ps) (new post-script-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[as-eps #t] [width width] [height height] [output output])]
[(pdf) (new pdf-dc%
[interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f]
[width width] [height height] [output output])]
[(svg) (new svg-dc%
[width width] [height height] [output output] [exists 'truncate/replace])]))
(define-values (x-scale y-scale) (send dc get-device-scale))
(send dc start-doc "Rendering plot")
(send dc start-page)
(plot3d/dc renderer-tree dc 0 0
(inexact->exact (/ width x-scale)) (inexact->exact (/ height y-scale))
#:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max
#:angle angle #:altitude altitude #:title title #:x-label x-label #:y-label y-label
#:z-label z-label #:legend-anchor legend-anchor)
(send dc end-page)
(send dc end-doc)])
(void))

View File

@ -10,7 +10,7 @@
unstable/contract)
plot
plot/utils
plot/doc
plot/private/doc
unstable/latent-contract/defthing)
(provide (all-defined-out)
@ -23,19 +23,17 @@
plot/utils
unstable/contract))
(all-from-out plot)
(all-from-out plot/doc)
(all-from-out plot/private/doc)
(all-from-out plot/utils)
doc-apply)
(define (plot-name) "PLoT")
(define (plot-name) "Plot")
(define plot-eval
(let ([eval (make-base-eval)])
(eval '(begin
(require racket/math racket/match racket/list racket/draw racket/class
(rename-in (except-in plot plot plot3d)
[plot-pict plot]
[plot3d-pict plot3d])
plot/pict
plot/utils)))
eval))

View File

@ -4,7 +4,8 @@
plot/compat)
plot/compat
(only-in unstable/latent-contract/defthing
doc-apply))
doc-apply)
(only-in "common.rkt" plot-name))
@title[#:tag "compat"]{Compatibility Module}
@ -12,7 +13,7 @@
@defmodule[plot/compat]
This module provides an interface compatible with PLoT 5.1.3 and earlier.
This module provides an interface compatible with @(plot-name) 5.1.3 and earlier.
@bold{Do not use both @racketmodname[plot] and @racketmodname[plot/compat] in the same module.}
It is tempting to try it, to get both the new features and comprehensive backward compatibility.

View File

@ -3,10 +3,11 @@
@(require "common.rkt"
(for-label (rename-in racket/draw [font-family/c ff/c])))
@declare-exporting[plot/utils]
@title[#:tag "contracts"]{Plot Contracts}
@declare-exporting[plot/utils]
@defmodule*/no-declare[(plot/utils) #:link-target? #f]
@section{Plot Element Contracts}
@defproc[(renderer2d? [value any/c]) boolean?]{

View File

@ -5,8 +5,7 @@
@title[#:tag "custom"]{Custom Plot Elements}
@declare-exporting[plot/utils]
The following API is provided by @racketmodname[plot/utils].
@defmodule*/no-declare[(plot/utils plot/typed/utils) #:link-target? #f]
@section{Plot Elements}

View File

@ -4,6 +4,8 @@
@title[#:tag "intro"]{Introduction}
@defmodule*/no-declare[(plot plot/typed) #:link-target? #f]
@section{Plotting 2D Graphs}
To plot a one-input, real-valued function, do something like
@ -11,12 +13,12 @@ To plot a one-input, real-valued function, do something like
@racketinput[(require plot)]
@interaction[#:eval plot-eval (plot (function sin (- pi) pi #:label "y = sin(x)"))]
(If you're not using DrRacket, start with
The first argument to @(racket function) is the function to be plotted, and the @(racket #:label) argument becomes the name of the function in the legend.
If you're not using DrRacket, start with
@racketblock[(require plot)
(plot-new-window? #t)]
to open each plot in a new window.)
The first argument to @(racket function) is the function to be plotted, and the @(racket #:label) argument becomes the name of the function in the legend.
to open each plot in a new window.
@section{Terminology}

View File

@ -3,6 +3,7 @@
@(require "common.rkt")
@declare-exporting[plot]
@defmodule*/no-declare[(plot plot/typed) #:link-target? #f]
@title[#:tag "nonrenderer"]{Nonrenderers}

View File

@ -2,10 +2,11 @@
@(require "common.rkt")
@declare-exporting[plot]
@title[#:tag "params"]{Plot and Renderer Parameters}
@declare-exporting[plot]
@defmodule*/no-declare[(plot plot/typed) #:link-target? #f]
@section{Compatibility}
@doc-apply[plot-deprecation-warnings?]{
@ -37,7 +38,7 @@ If @(racket #t), @(racket plot-file) and @(racket plot3d-file) open a dialog whe
@doc-apply[plot-background]{
The plot foreground and background color.
That both are @(racket 0) by default is not a mistake: for foreground colors, @(racket 0) is interpreted as black; for background colors, @(racket 0) is interpreted as white.
See @(racket ->pen-color) and @(racket ->brush-color) for details on how PLoT interprets integer colors.}
See @(racket ->pen-color) and @(racket ->brush-color) for details on how @(plot-name) interprets integer colors.}
@doc-apply[plot-foreground-alpha]
@doc-apply[plot-background-alpha]{The opacity of the background and foreground colors.}
@doc-apply[plot-font-size]{The font size of the title, axis labels, tick labels, and other labels, in drawing units.}
@ -93,7 +94,7 @@ Use these along with @racket[x-axis] and @racket[y-axis] if you want axes that i
}
@doc-apply[plot-animating?]{
When @(racket #t), certain renderers draw simplified plots to speed up drawing. PLoT sets it to @(racket #t), for example, when a user is clicking and dragging a 3D plot to rotate it.
When @(racket #t), certain renderers draw simplified plots to speed up drawing. @(plot-name) sets it to @(racket #t), for example, when a user is clicking and dragging a 3D plot to rotate it.
}
@doc-apply[animated-samples]{

View File

@ -17,22 +17,23 @@ Typed Racket users should use
It includes many common kinds already, such as scatter plots, line plots, contour plots, histograms, and 3D surfaces and isosurfaces.
Thanks to Racket's excellent multiple-backend drawing library, @(plot-name) can render plots as manipulatable images in DrRacket, as bitmaps in slideshows, as PNG, PDF, PS and SVG files, or on any device context.
For non-GUI uses, see @racketmodname[plot/no-gui].
For REPL-like environments outside of DrRacket (including Scribble manuals) in particular, see @racketmodname[plot/pict] and @racketmodname[plot/bitmap].
@bold{A note on backward compatibility.} @(plot-name) has undergone a major rewrite between versions 5.1.3 and 5.2.
Many programs written using PLoT 5.1.3 and earlier will still compile, run and generate plots.
Many programs written using @(plot-name) 5.1.3 and earlier will still compile, run and generate plots.
Some programs will not.
Most programs use deprecated functions such as @(racket mix), @(racket line) and @(racket surface). These functions still exist for backward compatibility, but are deprecated and may be removed in the future.
If you have code written for PLoT 5.1.3 or earlier, please see @secref["porting"] (and possibly @secref["compat"]).
If you have code written for @(plot-name) 5.1.3 or earlier, please see @secref["porting"] (and possibly @secref["compat"]).
@table-of-contents[]
@include-section["intro.scrbl"]
@include-section["plot2d.scrbl"]
@include-section["plotting.scrbl"]
@include-section["renderer2d.scrbl"]
@include-section["plot3d.scrbl"]
@include-section["renderer3d.scrbl"]
@include-section["nonrenderer.scrbl"]

View File

@ -1,96 +0,0 @@
#lang scribble/manual
@(require (for-label slideshow)
"common.rkt")
@declare-exporting[plot]
@title[#:tag "plot2d"]{2D Plot Procedures}
@defproc[(plot [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) (or/c (is-a?/c image-snip%) void?)]{
Plots a 2D renderer or list of renderers (or more generally, a tree of renderers), as returned by @(racket points), @(racket function), @(racket contours), @(racket discrete-histogram), and others.
By default, @(racket plot) produces a Racket value that is displayed as an image and can be manipulated like any other value.
For example, they may be put in lists:
@interaction[#:eval plot-eval
(parameterize ([plot-width 150]
[plot-height 150]
[plot-x-label #f]
[plot-y-label #f])
(list (plot (function sin (- pi) pi))
(plot (function sqr -2 2))))]
When the parameter @(racket plot-new-window?) is @(racket #t), @(racket plot) opens a new window to display the plot and returns @(racket (void)).
When @(racket #:out-file) is given, @(racket plot) writes the plot to a file using @(racket plot-file) as well as returning an @(racket image-snip%) or opening a new window.
When given, the @(racket x-min), @(racket x-max), @(racket y-min) and @(racket y-max) arguments determine the bounds of the plot, but not the bounds of the renderers. For example,
@interaction[#:eval plot-eval
(plot (function (λ (x) (sin (* 4 x))) -1 1)
#:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5)]
Here, the renderer draws in [-1,1] × [-1,1], but the plot area is [-1.5,1.5] × [-1.5,1.5].
@bold{Deprecated keywords.} The @(racket #:fgcolor) and @(racket #:bgcolor) keyword arguments are currently supported for backward compatibility, but may not be in the future.
Please set the @(racket plot-foreground) and @(racket plot-background) parameters instead of using these keyword arguments.
The @(racket #:lncolor) keyword argument is also accepted for backward compatibility but deprecated. It does nothing.
}
@deftogether[
(@defproc[(plot-file [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:<plot-keyword> <plot-keyword> <plot-keyword-contract>] ...) void?]
@defproc[(plot-pict [renderer-tree (treeof (or/c renderer2d? nonrenderer?))] ...) pict?]
@defproc[(plot-bitmap [renderer-tree (treeof (or/c renderer2d? nonrenderer?))] ...) (is-a?/c bitmap%)]
@defproc[(plot-snip [renderer-tree (treeof (or/c renderer2d? nonrenderer?))] ...) (is-a?/c image-snip%)]
@defproc[(plot-frame [renderer-tree (treeof (or/c renderer2d? nonrenderer?))] ...) (is-a?/c frame%)])]{
Plot to different backends. Each of these procedures has the same keyword arguments as @(racket plot), except for deprecated keywords.
Use @(racket plot-file) to save a plot to a file.
When creating a JPEG file, the parameter @(racket plot-jpeg-quality) determines its quality.
When creating a PostScript or PDF file, the parameter @(racket plot-ps/pdf-interactive?) determines whether the user is given a dialog for setting printing parameters.
(See @(racket post-script-dc%) and @(racket pdf-dc%).)
When @(racket kind) is @(racket 'auto), @(racket plot-file) tries to determine the kind of file to write from the file name extension.
Use @(racket plot-pict) to plot to a slideshow @(racket pict). For example,
@racketmod[slideshow
(require plot)
(plot-font-size (current-font-size))
(plot-width (current-para-width))
(plot-height 600)
(plot-background-alpha 1/2)
(slide
#:title "A 2D Parabola"
(plot-pict (function sqr -1 1 #:label "y = x^2")))]
creates a slide containing a 2D plot of a parabola.
Use @(racket plot-bitmap) to create a @(racket bitmap%).
Use @(racket plot-frame) to create a @(racket frame%) regardless of the value of @(racket plot-new-window?). The frame is initially hidden.
Use @(racket plot-snip) to create an interactive @(racket image-snip%) regardless of the value of @(racket plot-new-window?).
}
@doc-apply[plot/dc]{
Plots to an arbitrary device context, in the rectangle with width @(racket width), height @(racket height), and upper-left corner @(racket x),@(racket y).
Every @secref{plot2d} procedure is defined in terms of @(racket plot/dc).
Use this if you need to continually update a plot on a @(racket canvas%), or to create other @(racket plot)-like functions with different backends.
}

View File

@ -1,64 +0,0 @@
#lang scribble/manual
@(require "common.rkt")
@declare-exporting[plot]
@title[#:tag "plot3d"]{3D Plot Procedures}
Each 3D plot procedure corresponds with a @(secref "plot2d") procedure. Each behaves the same way as its corresponding 2D procedure, but takes the additional keyword arguments @(racket #:z-min), @(racket #:z-max), @(racket #:angle), @(racket #:altitude) and @(racket #:z-label).
@defproc[(plot3d [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) (or/c (is-a?/c image-snip%) void?)]{
This procedure corresponds with @(racket plot). It plots a 3D renderer or list of renderers (or more generally, a tree of renderers), as returned by @(racket points3d), @(racket parametric3d), @(racket surface3d), @(racket isosurface3d), and others.
When the parameter @(racket plot-new-window?) is @(racket #t), @(racket plot3d) opens a new window to display the plot and returns @(racket (void)).
When @(racket #:out-file) is given, @(racket plot3d) writes the plot to a file using @(racket plot3d-file) as well as returning a @(racket image-snip%) or opening a new window.
When given, the @(racket x-min), @(racket x-max), @(racket y-min), @(racket y-max), @(racket z-min) and @(racket z-max) arguments determine the bounds of the plot, but not the bounds of the renderers.
@bold{Deprecated keywords.} The @(racket #:fgcolor) and @(racket #:bgcolor) keyword arguments are currently supported for backward compatibility, but may not be in the future.
Please set the @(racket plot-foreground) and @(racket plot-background) parameters instead of using these keyword arguments.
The @(racket #:lncolor) keyword argument is also accepted for backward compatibility but deprecated. It does nothing.
The @(racket #:az) and @(racket #:alt) keyword arguments are backward-compatible, deprecated aliases for @(racket #:angle) and @(racket #:altitude), respectively.
}
@deftogether[
(@defproc[(plot3d-file [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:<plot-keyword> <plot-keyword> <plot-keyword-contract>] ...) void?]
@defproc[(plot3d-pict [renderer-tree (treeof (or/c renderer3d? nonrenderer?))] ...) pict?]
@defproc[(plot3d-bitmap [renderer-tree (treeof (or/c renderer3d? nonrenderer?))] ...) (is-a?/c bitmap%)]
@defproc[(plot3d-snip [renderer-tree (treeof (or/c renderer3d? nonrenderer?))] ...) (is-a?/c image-snip%)]
@defproc[(plot3d-frame [renderer-tree (treeof (or/c renderer3d? nonrenderer?))] ...) (is-a?/c frame%)])]{
Plot to different backends. Each of these procedures has the same keyword arguments as @(racket plot3d), except for deprecated keywords.
These procedures correspond with @(racket plot-file), @(racket plot-pict), @(racket plot-bitmap), @(racket plot-snip) and @(racket plot-frame).
}
@doc-apply[plot3d/dc]{
Plots to an arbitrary device context, in the rectangle with width @(racket width), height @(racket height), and upper-left corner @(racket x),@(racket y).
Every @secref{plot3d} procedure is defined in terms of @(racket plot3d/dc).
Use this if you need to continually update a plot on a @(racket canvas%), or to create other @(racket plot3d)-like functions with different backends.
This procedure corresponds with @(racket plot/dc).
}

View File

@ -0,0 +1,221 @@
#lang scribble/manual
@(require (for-label slideshow
racket/gui/dynamic)
"common.rkt")
@declare-exporting[plot]
@title[#:tag "plotting"]{2D and 3D Plotting Procedures}
The plotting procedures exported by @racketmodname[plot/no-gui] produce @racket[bitmap%] and @racket[pict] instances, and write to files.
They do not require @racketmodname[racket/gui], so they work in headless environments; for example, a Linux terminal with @tt{DISPLAY} unset.
The @racketmodname[plot] module re-exports everything exported by @racketmodname[plot/no-gui], as well as @racket[plot], @racket[plot3d], and other procedures that create interactive plots and plot frames.
Interactive plotting procedures can always be imported, but fail when called if there is no working display or @racketmodname[racket/gui] is not present.
Each 3D plotting procedure behaves the same way as its corresponding 2D procedure, but takes the additional keyword arguments @(racket #:z-min), @(racket #:z-max), @(racket #:angle), @(racket #:altitude) and @(racket #:z-label).
@section{GUI Plotting Procedures}
@defmodule*/no-declare[(plot plot/typed) #:link-target? #f]
@defproc[(plot [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[#: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]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) (or/c (is-a?/c image-snip%) void?)]{
Plots a 2D renderer or list of renderers (or more generally, a tree of renderers), as returned by @(racket points), @(racket function), @(racket contours), @(racket discrete-histogram), and others.
By default, @(racket plot) produces a Racket value that is displayed as an image and can be manipulated like any other value.
For example, they may be put in lists:
@interaction[#:eval plot-eval
(parameterize ([plot-width 150]
[plot-height 150]
[plot-x-label #f]
[plot-y-label #f])
(list (plot (function sin (- pi) pi))
(plot (function sqr -2 2))))]
When the parameter @(racket plot-new-window?) is @(racket #t), @(racket plot) opens a new window to display the plot and returns @(racket (void)).
When @(racket #:out-file) is given, @(racket plot) writes the plot to a file using @(racket plot-file) as well as returning an @(racket image-snip%) or opening a new window.
When given, the @(racket x-min), @(racket x-max), @(racket y-min) and @(racket y-max) arguments determine the bounds of the plot, but not the bounds of the renderers. For example,
@interaction[#:eval plot-eval
(plot (function (λ (x) (sin (* 4 x))) -1 1)
#:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5)]
Here, the renderer draws in [-1,1] × [-1,1], but the plot area is [-1.5,1.5] × [-1.5,1.5].
@bold{Deprecated keywords.} The @(racket #:fgcolor) and @(racket #:bgcolor) keyword arguments are currently supported for backward compatibility, but may not be in the future.
Please set the @(racket plot-foreground) and @(racket plot-background) parameters instead of using these keyword arguments.
The @(racket #:lncolor) keyword argument is also accepted for backward compatibility but deprecated. It does nothing.
}
@defproc[(plot3d [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[#: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]
[#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f]
[#:width width exact-positive-integer? (plot-width)]
[#:height height exact-positive-integer? (plot-height)]
[#:angle angle real? (plot3d-angle)]
[#:altitude altitude real? (plot3d-altitude)]
[#:title title (or/c string? #f) (plot-title)]
[#:x-label x-label (or/c string? #f) (plot-x-label)]
[#:y-label y-label (or/c string? #f) (plot-y-label)]
[#:z-label z-label (or/c string? #f) (plot-z-label)]
[#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)]
[#:out-file out-file (or/c path-string? output-port? #f) #f]
[#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
) (or/c (is-a?/c image-snip%) void?)]{
Plots a 3D renderer or list of renderers (or more generally, a tree of renderers), as returned by @(racket points3d), @(racket parametric3d), @(racket surface3d), @(racket isosurface3d), and others.
When the parameter @(racket plot-new-window?) is @(racket #t), @(racket plot3d) opens a new window to display the plot and returns @(racket (void)).
When @(racket #:out-file) is given, @(racket plot3d) writes the plot to a file using @(racket plot3d-file) as well as returning a @(racket image-snip%) or opening a new window.
When given, the @(racket x-min), @(racket x-max), @(racket y-min), @(racket y-max), @(racket z-min) and @(racket z-max) arguments determine the bounds of the plot, but not the bounds of the renderers.
@bold{Deprecated keywords.} The @(racket #:fgcolor) and @(racket #:bgcolor) keyword arguments are currently supported for backward compatibility, but may not be in the future.
Please set the @(racket plot-foreground) and @(racket plot-background) parameters instead of using these keyword arguments.
The @(racket #:lncolor) keyword argument is also accepted for backward compatibility but deprecated. It does nothing.
The @(racket #:az) and @(racket #:alt) keyword arguments are backward-compatible, deprecated aliases for @(racket #:angle) and @(racket #:altitude), respectively.
}
@defproc[(plot-snip [<plot-argument> <plot-argument-contract>] ...)
(is-a?/c image-snip%)]
@defproc[(plot3d-snip [<plot-argument> <plot-argument-contract>] ...)
(is-a?/c image-snip%)]
@defproc[(plot-frame [<plot-argument> <plot-argument-contract>] ...)
(is-a?/c frame%)]
@defproc[(plot3d-frame [<plot-argument> <plot-argument-contract>] ...)
(is-a?/c frame%)]{
Plot to different GUI backends.
These procedures accept the same arguments as @(racket plot) and @(racket plot3d), except deprecated keywords, and @racket[#:out-file] and @racket[#:out-kind].
Use @(racket plot-frame) and @(racket plot3d-frame) to create a @(racket frame%) regardless of the value of @(racket plot-new-window?). The frame is initially hidden.
Use @(racket plot-snip) and @(racket plot3d-snip) to create an interactive @(racket image-snip%) regardless of the value of @(racket plot-new-window?).
}
@section{Non-GUI Plotting Procedures}
@defmodule*/no-declare[(plot/no-gui plot/typed/no-gui)]
@defproc[(plot-file [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:<plot-keyword> <plot-keyword> <plot-keyword-contract>] ...)
void?]
@defproc[(plot3d-file [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[output (or/c path-string? output-port?)]
[kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto]
[#:<plot3d-keyword> <plot3d-keyword> <plot3d-keyword-contract>] ...)
void?]
@defproc[(plot-pict [<plot-argument> <plot-argument-contract>] ...)
pict?]
@defproc[(plot3d-pict [<plot3d-argument> <plot3d-argument-contract>] ...)
pict?]
@defproc[(plot-bitmap [<plot-argument> <plot-argument-contract>] ...)
(is-a?/c bitmap%)]
@defproc[(plot3d-bitmap [<plot3d-argument> <plot3d-argument-contract>] ...)
(is-a?/c bitmap%)]{
Plot to different non-GUI backends.
These procedures accept the same arguments as @(racket plot) and @(racket plot3d), except deprecated keywords, and @racket[#:out-file] and @racket[#:out-kind].
Use @(racket plot-file) or @(racket plot3d-file) to save a plot to a file.
When creating a JPEG file, the parameter @(racket plot-jpeg-quality) determines its quality.
When creating a PostScript or PDF file, the parameter @(racket plot-ps/pdf-interactive?) determines whether the user is given a dialog to set printing parameters.
(See @(racket post-script-dc%) and @(racket pdf-dc%).)
When @(racket kind) is @(racket 'auto), @(racket plot-file) and @(racket plot3d-file) try to determine from the file name extension the kind of file to write.
Use @(racket plot-pict) or @(racket plot3d-pict) to create a @(racket pict).
For example, this program creates a slide containing a 2D plot of a parabola:
@racketmod[slideshow
(require plot)
(plot-font-size (current-font-size))
(plot-width (current-para-width))
(plot-height 600)
(plot-background-alpha 1/2)
(slide
#:title "A 2D Parabola"
(plot-pict (function sqr -1 1 #:label "y = x^2")))]
Use @(racket plot-bitmap) or @(racket plot3d-bitmap) to create a @(racket bitmap%).
}
@defproc[(plot/dc [renderer-tree (treeof (or/c renderer2d? nonrenderer?))]
[dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[width (>=/c 0)]
[height (>=/c 0)]
[#:<plot-keyword> <plot-keyword> <plot-keyword-contract>] ...)
void?]
@defproc[(plot3d/dc [renderer-tree (treeof (or/c renderer3d? nonrenderer?))]
[dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[width (>=/c 0)]
[height (>=/c 0)]
[#:<plot3d-keyword> <plot3d-keyword> <plot3d-keyword-contract>] ...)
void?]{
Plot to an arbitrary device context, in the rectangle with width @(racket width), height @(racket height), and upper-left corner @(racket x),@(racket y).
These procedures accept the same arguments as @(racket plot) and @(racket plot3d), except deprecated keywords, and @racket[#:out-file] and @racket[#:out-kind].
Use these if you need to continually update a plot on a @(racket canvas%), or to create other @(racket plot)-like functions with different backends.
}
@section{Pict-Plotting Work-a-Likes}
@declare-exporting[plot/pict]
@defmodule*/no-declare[(plot/pict plot/typed/pict)]
When setting up an evaluator for a Scribble manual, require @racketmodname[plot/pict] instead of @racketmodname[plot].
Evaluation will produce picts instead of snips, which scale nicely in PDF-rendered documentation.
For example, this is how the evaluator for the @(plot-name) documentation is defined:
@racketblock[
(define plot-eval
(let ([eval (make-base-eval)])
(eval '(begin
(require racket/math
racket/match
racket/list
racket/draw
racket/class
plot/pict
plot/utils)))
eval))]
If you use @racket[(require (for-label plot))], links in example code should resolve to documentation for the functions exported by @racketmodname[plot].
@defproc[(plot [<plot-argument> <plot-argument-contract>] ...) pict?]
@defproc[(plot3d [<plot3d-argument> <plot3d-argument-contract>] ...) pict?]{
Like the functions of the same name exported from @racketmodname[plot], but these produce @racket[pict] instances instead of interactive snips.
}
@section{Bitmap-Plotting Work-a-Likes}
@declare-exporting[plot/bitmap]
@defmodule*/no-declare[(plot/bitmap plot/typed/bitmap)]
When plotting in an environment where @racket[bitmap%] instances can be shown but @racket[snip%] instances cannot (for example, on a web page that evaluates Racket code), require @racketmodname[plot/bitmap] instead of @racketmodname[plot].
@defproc[(plot [<plot-argument> <plot-argument-contract>] ...) (is-a?/c bitmap%)]
@defproc[(plot3d [<plot3d-argument> <plot3d-argument-contract>] ...) (is-a?/c bitmap%)]{
Like the functions of the same name exported from @racketmodname[plot], but these produce @racket[bitmap%] instances instead of interactive snips.
}

View File

@ -2,27 +2,25 @@
@(require "common.rkt")
@declare-exporting[plot]
@title[#:tag "porting"]{Porting From PLoT <= 5.1.3}
@title[#:tag "porting"]{Porting From @(plot-name) <= 5.1.3}
If it seems porting will take too long, you can get your old code running more quickly using the @secref["compat"].
The update from PLoT version 5.1.3 to 5.2 introduces a few incompatibilities:
The update from @(plot-name) version 5.1.3 to 5.2 introduces a few incompatibilities:
@itemlist[
@item{PLoT now allows plot elements to request plot area bounds, and finds bounds large enough to fit all plot elements.
@item{@(plot-name) now allows plot elements to request plot area bounds, and finds bounds large enough to fit all plot elements.
The old default plot area bounds of [-5,5] × [-5,5] cannot be made consistent with the improved behavior; the default bounds are now "no bounds".
This causes code such as @(racket (plot (line sin))), which does not state bounds, to fail.}
@item{The @(racket #:width) and @(racket #:style) keyword arguments to @(racket vector-field) have been replaced by @(racket #:line-width) and @(racket #:scale) to be consistent with other functions.}
@item{The @(racket plot) function no longer takes a @(racket ((is-a?/c 2d-view%) . -> . void?)) as an argument, but a @(racket (treeof renderer2d?)).
The argument change in @(racket plot3d) is similar.
This should not affect most code because PLoT encourages regarding these data types as black boxes.}
This should not affect most code because @(plot-name) encourages regarding these data types as black boxes.}
@item{The @(racket plot-extend) module no longer exists.}
@item{The @racket[fit] function and @racket[fit-result] struct type have been removed.}
]
This section of the PLoT manual will help you port code written for PLoT 5.1.3 and earlier to the most recent PLoT.
This section of the @(plot-name) manual will help you port code written for @(plot-name) 5.1.3 and earlier to the most recent @(plot-name).
There are four main tasks:
@itemlist[
@item{Replace deprecated functions.}
@ -50,7 +48,7 @@ The number of contour levels is therefore some number between @(racket 4) and @(
The safest way to ensure that @(racket plot) can determine bounds for the plot area is to add @(racket #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5) to every call to @(racket plot). Similarly, add @(racket #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5 #:z-min -5 #:z-max 5) to every call to @(racket plot3d).
Because PLoT is now smarter about choosing bounds, there are better ways. For example, suppose you have
Because @(plot-name) is now smarter about choosing bounds, there are better ways. For example, suppose you have
@interaction[#:eval plot-eval
(eval:alts
@ -106,13 +104,16 @@ For example, if @(racket vs) is the list of vectors, send @(racket (map (λ (v)
Chances are, if you used @(racket plot-extend), you no longer need it.
The canonical @(racket plot-extend) example used to be a version of @(racket line) that drew dashed lines.
Every line-drawing function in PLoT now has a @(racket #:style) or @(racket #:line-style) keyword argument.
Every line-drawing function in @(plot-name) now has a @(racket #:style) or @(racket #:line-style) keyword argument.
The rewritten PLoT will eventually have a similar extension mechanism.
The rewritten @(plot-name) will eventually have a similar extension mechanism.
@section{Deprecated Functions}
@declare-exporting[plot]
@defmodule*/no-declare[(plot) #:link-target? #f]
The following functions exist for backward compatibility, but may be removed in the future.
Set @(racket (plot-deprecation-warnings? #t)) to be alerted the first time each is used.

View File

@ -2,10 +2,11 @@
@(require "common.rkt")
@declare-exporting[plot]
@title[#:tag "renderer2d"]{2D Renderers}
@declare-exporting[plot]
@defmodule*/no-declare[(plot plot/typed) #:link-target? #f]
@section[#:tag "renderer2d-function-arguments"]{2D Renderer Function Arguments}
Functions that return 2D renderers always have these kinds of arguments:

View File

@ -2,10 +2,11 @@
@(require "common.rkt")
@declare-exporting[plot]
@title[#:tag "renderer3d"]{3D Renderers}
@declare-exporting[plot]
@defmodule*/no-declare[(plot plot/typed) #:link-target? #f]
@section{3D Renderer Function Arguments}
As with functions that return 2D renderers, functions that return 3D renderers always have these kinds of arguments:

View File

@ -2,10 +2,11 @@
@(require "common.rkt" (for-label racket/date db))
@declare-exporting[plot]
@title[#:tag "ticks and transforms"]{Axis Transforms and Ticks}
@declare-exporting[plot]
@defmodule*/no-declare[(plot plot/typed) #:link-target? #f]
@section[#:tag "transforms"]{Axis Transforms}
The @italic{x}, @italic{y} and @italic{z} axes for any plot can be independently transformed by parameterizing the plot on different @racket[plot-x-transform], @racket[plot-y-transform] and @racket[plot-z-transform] values.
@ -38,7 +39,7 @@ Here, the renderer returned by @racket[surface3d] does not have to bend the poly
@doc-apply[plot-x-transform]
@doc-apply[plot-y-transform]
@doc-apply[plot-z-transform]{
Independent, per-axis, monotone, nonlinear transforms. PLoT comes with some typical (and some atypical) axis transforms, documented immediately below.
Independent, per-axis, monotone, nonlinear transforms. @(plot-name) comes with some typical (and some atypical) axis transforms, documented immediately below.
}
@doc-apply[id-transform]{
@ -358,7 +359,7 @@ The @racket[#:formats] keyword argument is a list of three format strings, repre
@doc-apply[currency-ticks-formats]{
The default currency scales and formats.
For example, a PLoT user in France would probably begin programs with
For example, a @(plot-name) user in France would probably begin programs with
@racketblock[(require plot)
(currency-ticks-scales eu-currency-scales)
(currency-ticks-formats eu-currency-formats)]

View File

@ -4,11 +4,8 @@
@title[#:tag "utils"]{Plot Utilities}
@defmodule[plot/utils]
Typed Racket users should use
@defmodule*/no-declare[(plot/typed/utils)]
@declare-exporting[plot/utils]
@defmodule*/no-declare[(plot/utils plot/typed/utils)]
@;====================================================================================================
@section{Formatting}
@ -66,7 +63,7 @@ Converts an integer into a string of superscript Unicode characters.
@examples[#:eval plot-eval
(integer->superscript -1234567890)]
Systems running some out-of-date versions of Windows XP have difficulty with Unicode superscripts for 4 and up.
Because @racket[integer->superscript] is used by every number formatting function to format exponents, if you have such a system, PLoT will apparently not format all numbers with exponents correctly (until you update it).
Because @racket[integer->superscript] is used by every number formatting function to format exponents, if you have such a system, @(plot-name) will apparently not format all numbers with exponents correctly (until you update it).
}
@;{
@ -453,7 +450,7 @@ Use this to construct inputs for @(racket rectangles) and @(racket rectangles3d)
@subsection[#:tag "math.rectangles"]{Rectangles and Rectangle Functions}
@margin-note*{The @racket[rect-meet] and @racket[rect-join] functions define a @link["http://en.wikipedia.org/wiki/Lattice_%28order%29"]{pointed lattice} over rectangles.
This fact may seem esoteric, but it allows PLoT to combine multiple renderers with different rectangular bounds in a way that is intuitive and mathematically sound.}
This fact may seem esoteric, but it allows @(plot-name) to combine multiple renderers with different rectangular bounds in a way that is intuitive and mathematically sound.}
@defproc[(rect-meet [i (vectorof ivl?)] ...) (vectorof ivl?)]{
}
@ -505,7 +502,7 @@ To keep time zone offsets from influencing the plot, set them to @racket[0] firs
[day exact-integer?])]{
A time representation that accounts for days, negative times (using negative days), and fractional seconds.
PLoT (specifically @racket[time-ticks]) uses @racket[plot-time] internally to format times, but because renderer-producing functions require only real values,
@(plot-name) (specifically @racket[time-ticks]) uses @racket[plot-time] internally to format times, but because renderer-producing functions require only real values,
user code should not need it. It is provided just in case.
}

View File

@ -1,6 +1,6 @@
#lang racket
(require plot/doc
(require plot/private/doc
scribble/manual
scribble/render
scribble/text-render

View File

@ -2,20 +2,20 @@
(require rackunit racket/date
plot plot/utils
plot/common/utils
(only-in plot/common/math
plot/private/common/utils
(only-in plot/private/common/math
vector-andmap
vector-ormap)
(only-in plot/common/date-time
(only-in plot/private/common/date-time
utc-seconds-round-year
utc-seconds-round-month
seconds-per-minute
seconds-per-hour
seconds-per-day
seconds-per-week)
(only-in plot/common/format
(only-in plot/private/common/format
int-str->e-str frac-str->e-str)
plot/common/worker-thread)
plot/private/common/worker-thread)
(check-equal? (linear-seq 1 1 2) '(1 1))
(check-equal? (linear-seq 0 1 2 #:start? #t #:end? #t) '(0 1))

View File

@ -0,0 +1,17 @@
#lang racket
(require rackunit
plot/bitmap
racket/draw)
(check-true (is-a? (plot (function sin -4 4)
#:out-file "sin.png")
bitmap%))
(check-true (is-a? (read-bitmap "sin.png") bitmap%))
(delete-file "sin.png")
(check-true (is-a? (plot3d (contour-intervals3d * -4 4 -4 4)
#:out-file "times.png")
bitmap%))
(check-true (is-a? (read-bitmap "times.png") bitmap%))
(delete-file "times.png")

View File

@ -0,0 +1,20 @@
#lang racket
(require rackunit
plot/no-gui
pict
racket/draw)
(check-true (pict? (plot-pict (function sin -4 4))))
(check-true (pict? (plot3d-pict (contour-intervals3d * -4 4 -4 4))))
(check-true (is-a? (plot-bitmap (function sin -4 4)) bitmap%))
(check-true (is-a? (plot3d-bitmap (contour-intervals3d * -4 4 -4 4)) bitmap%))
(check-true (void? (plot-file (function sin -4 4) "sin.png")))
(check-true (is-a? (read-bitmap "sin.png") bitmap%))
(delete-file "sin.png")
(check-true (void? (plot3d-file (contour-intervals3d * -4 4 -4 4) "times.png")))
(check-true (is-a? (read-bitmap "times.png") bitmap%))
(delete-file "times.png")

View File

@ -0,0 +1,16 @@
#lang racket
(require rackunit
plot/pict
pict
racket/draw)
(check-true (pict? (plot (function sin -4 4)
#:out-file "sin.png")))
(check-true (is-a? (read-bitmap "sin.png") bitmap%))
(delete-file "sin.png")
(check-true (pict? (plot3d (contour-intervals3d * -4 4 -4 4)
#:out-file "times.png")))
(check-true (is-a? (read-bitmap "times.png") bitmap%))
(delete-file "times.png")

View File

@ -1,6 +1,8 @@
#lang racket
(require plot plot/plot2d/plot-area plot/plot3d/plot-area)
(require plot
plot/private/plot2d/plot-area
plot/private/plot3d/plot-area)
(parameterize ([plot-x-transform log-transform]
[plot-x-ticks (log-ticks)])

Some files were not shown because too many files have changed in this diff Show More