Skip to content

Commit 0dbfad4

Browse files
authored
Allow picts to be used as legend entries in plots (#64)
Allow pictures to be used as legend entries in plots Updated 2D and 3D plot renderers to accept a picture (from the pict library) or a string as the label used in the plot legend. The original request was to allow LaTeX notation for the labels, this changeset will enable doing that (and more) by installing the additional `latex-pict` package and using the pictures produced by that package as labels. When updated the code which draws the legend, several considerations were made: * the `get-text-extent` method of `plot-device%` accepts a pict as an argument and will return the picture dimensions in that case. The method was not renamed, however. * the font used for text legend entries determines the inset (inside border) of the legend, gap between entries and length of the "sample" line. This was essentially unchanged behavior and using the pict dimensions for this purpose results in bad looking legends, where the inset is too small, the sample line too long and gap too big. Also updated some of the examples in the documentation to replace x^2 with x², to illustrate that Unicode can be used for the string labels. See also * #58 * racket/racket#3321
1 parent 58b5d7e commit 0dbfad4

File tree

24 files changed

+318
-136
lines changed

24 files changed

+318
-136
lines changed

plot-doc/plot/scribblings/contracts.scrbl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ Like @(racket plot-colors/c), but for fill styles.
202202
Like @(racket plot-colors/c), but for opacities.
203203
}
204204

205-
@defproc[(labels/c [in-contract contract?]) contract? #:value (maybe-function/c in-contract (listof (or/c string? #f)))]{
205+
@defproc[(labels/c [in-contract contract?]) contract? #:value (maybe-function/c in-contract (listof (or/c string? pict? #f)))]{
206206
Like @racket[plot-colors/c], but for strings.
207207
This is used, for example, to label @racket[stacked-histogram]s.
208208
}

plot-doc/plot/scribblings/renderer2d.scrbl

Lines changed: 73 additions & 25 deletions
Large diffs are not rendered by default.

plot-doc/plot/scribblings/renderer3d.scrbl

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ See @secref["renderer2d-function-arguments"] for a detailed example.
3434
[#:size size (>=/c 0) (point-size)]
3535
[#:line-width line-width (>=/c 0) (point-line-width)]
3636
[#:alpha alpha (real-in 0 1) (point-alpha)]
37-
[#:label label (or/c string? #f) #f]
37+
[#:label label (or/c string? pict? #f) #f]
3838
) renderer3d?]{
3939
Returns a renderer that draws points in 3D space.
4040

@@ -62,6 +62,8 @@ negative direction, so total spread along e.g. the x-axis is twice @racket[x-jit
6262

6363
Note that adding random noise to data, via jittering or otherwise, is usually a bad idea.
6464
See the documentation for @racket[points] for examples where jittering may be appropriate.
65+
66+
@history[#:changed "7.9" "Added support for pictures for #:label"]
6567
}
6668

6769
@defproc[(vector-field3d
@@ -76,13 +78,15 @@ See the documentation for @racket[points] for examples where jittering may be ap
7678
[#:line-width line-width (>=/c 0) (vector-field-line-width)]
7779
[#:line-style line-style plot-pen-style/c (vector-field-line-style)]
7880
[#:alpha alpha (real-in 0 1) (vector-field-alpha)]
79-
[#:label label (or/c string? #f) #f]
81+
[#:label label (or/c string? pict? #f) #f]
8082
) renderer3d?]{
8183
Returns a renderer that draws a vector field in 3D space.
8284
The arguments are interpreted identically to the corresponding arguments to @racket[vector-field].
8385
@examples[#:eval plot-eval
8486
(plot3d (vector-field3d (λ (x y z) (vector x z y))
8587
-2 2 -2 2 -2 2))]
88+
89+
@history[#:changed "7.9" "Added support for pictures for #:label"]
8690
}
8791

8892
@section{3D Line Renderers}
@@ -96,10 +100,12 @@ The arguments are interpreted identically to the corresponding arguments to @rac
96100
[#:width width (>=/c 0) (line-width)]
97101
[#:style style plot-pen-style/c (line-style)]
98102
[#:alpha alpha (real-in 0 1) (line-alpha)]
99-
[#:label label (or/c string? #f) #f]
103+
[#:label label (or/c string? pict? #f) #f]
100104
) renderer3d?]{
101105
Returns a renderer that draws connected lines.
102106
The @racket[parametric3d] function is defined in terms of this one.
107+
108+
@history[#:changed "7.9" "Added support for pictures for #:label"]
103109
}
104110

105111
@defproc[(parametric3d
@@ -113,14 +119,16 @@ The @racket[parametric3d] function is defined in terms of this one.
113119
[#:width width (>=/c 0) (line-width)]
114120
[#:style style plot-pen-style/c (line-style)]
115121
[#:alpha alpha (real-in 0 1) (line-alpha)]
116-
[#:label label (or/c string? #f) #f]
122+
[#:label label (or/c string? pict? #f) #f]
117123
) renderer3d?]{
118124
Returns a renderer that plots a vector-valued function of time. For example,
119125
@interaction[#:eval plot-eval
120126
(require (only-in plot/utils 3d-polar->3d-cartesian))
121127
(plot3d (parametric3d (λ (t) (3d-polar->3d-cartesian (* t 80) t 1))
122128
(- pi) pi #:samples 3000 #:alpha 0.5)
123129
#:altitude 25)]
130+
131+
@history[#:changed "7.9" "Added support for pictures for #:label"]
124132
}
125133

126134
@section{3D Surface Renderers}
@@ -137,14 +145,16 @@ Returns a renderer that plots a vector-valued function of time. For example,
137145
[#:line-width line-width (>=/c 0) (surface-line-width)]
138146
[#:line-style line-style plot-pen-style/c (surface-line-style)]
139147
[#:alpha alpha (real-in 0 1) (surface-alpha)]
140-
[#:label label (or/c string? #f) #f]
148+
[#:label label (or/c string? pict? #f) #f]
141149
) renderer3d?]{
142150
Returns a renderer that plots a two-input, one-output function. For example,
143151
@interaction[#:eval plot-eval (plot3d (list (surface3d (λ (x y) (+ (sqr x) (sqr y))) -1 1 -1 1
144-
#:label "z = x^2 + y^2")
152+
#:label "z = x² + y²")
145153
(surface3d (λ (x y) (- (+ (sqr x) (sqr y)))) -1 1 -1 1
146154
#:color 4 #:line-color 4
147-
#:label "z = -x^2 - y^2")))]
155+
#:label "z = -x² - y²")))]
156+
157+
@history[#:changed "7.9" "Added support for pictures for #:label"]
148158
}
149159

150160
@defproc[(polar3d
@@ -159,7 +169,7 @@ Returns a renderer that plots a two-input, one-output function. For example,
159169
[#:line-width line-width (>=/c 0) (surface-line-width)]
160170
[#:line-style line-style plot-pen-style/c (surface-line-style)]
161171
[#:alpha alpha (real-in 0 1) (surface-alpha)]
162-
[#:label label (or/c string? #f) #f]
172+
[#:label label (or/c string? pict? #f) #f]
163173
) renderer3d?]{
164174
Returns a renderer that plots a function from longitude and latitude to radius.
165175
@racket[(f θ ϕ)] → @racket[r]
@@ -181,6 +191,8 @@ Combining polar function renderers allows faking latitudes or longitudes in larg
181191
#:line-style 'transparent #:alpha 2/3)
182192
(polar3d f2 #:color "navajowhite"
183193
#:line-style 'transparent #:alpha 2/3))))]
194+
195+
@history[#:changed "7.9" "Added support for pictures for #:label"]
184196
}
185197

186198
@defproc[(parametric-surface3d
@@ -199,7 +211,7 @@ Combining polar function renderers allows faking latitudes or longitudes in larg
199211
[#:line-width line-width (>=/c 0) (surface-line-width)]
200212
[#:line-style line-style plot-pen-style/c (surface-line-style)]
201213
[#:alpha alpha (real-in 0 1) (surface-alpha)]
202-
[#:label label (or/c string? #f) #f]
214+
[#:label label (or/c string? pict? #f) #f]
203215
) renderer3d?]{
204216
Returns a renderer that plots a two-input, one-output function. @racket[(f s t)] → @racket['(x y z)]
205217

@@ -225,6 +237,8 @@ For example,
225237
#:label "torus2"))
226238
#:z-min -6 #:z-max 6
227239
#:altitude 22)]
240+
241+
@history[#:changed "7.9" "Added support for pictures for #:label"]
228242
}
229243

230244
@defproc[(polygons3d
@@ -238,7 +252,7 @@ For example,
238252
[#:line-width line-width (>=/c 0) (surface-line-width)]
239253
[#:line-style line-style plot-pen-style/c (surface-line-style)]
240254
[#:alpha alpha (real-in 0 1) (surface-alpha)]
241-
[#:label label (or/c string? #f) #f]
255+
[#:label label (or/c string? pict? #f) #f]
242256
) renderer3d?]{
243257
Returns a renderer that draws polygons.
244258
The @racket[parametric-surface3d] function is defined in terms of this one.
@@ -248,6 +262,8 @@ The @racket[parametric-surface3d] function is defined in terms of this one.
248262
(list (list 1 0 0)(list 0 1 0)(list 0 0 0))))
249263
#:angle 355
250264
#:altitude 30)]
265+
266+
@history[#:changed "7.9" "Added support for pictures for #:label"]
251267
}
252268

253269
@section{3D Contour (Isoline) Renderers}
@@ -262,7 +278,7 @@ The @racket[parametric-surface3d] function is defined in terms of this one.
262278
[#:width width (>=/c 0) (line-width)]
263279
[#:style style plot-pen-style/c (line-style)]
264280
[#:alpha alpha (real-in 0 1) (line-alpha)]
265-
[#:label label (or/c string? #f) #f]
281+
[#:label label (or/c string? pict? #f) #f]
266282
) renderer3d?]{
267283
Returns a renderer that plots a single contour line on the surface of a function.
268284

@@ -273,6 +289,8 @@ This function is not terribly useful by itself, but can be when combined with ot
273289
(define (saddle x y) (- (sqr x) (sqr y)))
274290
(plot3d (list (surface3d saddle -1 1 -1 1)
275291
(isoline3d saddle 1/4 #:width 2 #:style 'long-dash)))]
292+
293+
@history[#:changed "7.9" "Added support for pictures for #:label"]
276294
}
277295

278296
@defproc[(contours3d
@@ -286,7 +304,7 @@ This function is not terribly useful by itself, but can be when combined with ot
286304
[#:widths widths (pen-widths/c (listof real?)) (contour-widths)]
287305
[#:styles styles (plot-pen-styles/c (listof real?)) (contour-styles)]
288306
[#:alphas alphas (alphas/c (listof real?)) (contour-alphas)]
289-
[#:label label (or/c string? #f) #f]
307+
[#:label label (or/c string? pict? #f) #f]
290308
) renderer3d?]{
291309
Returns a renderer that plots contour lines on the surface of a function.
292310

@@ -295,7 +313,9 @@ In particular, when @(racket levels) is @(racket 'auto), contour values correspo
295313

296314
For example,
297315
@interaction[#:eval plot-eval (plot3d (contours3d (λ (x y) (+ (sqr x) (sqr y))) -1.1 1.1 -1.1 1.1
298-
#:label "z = x^2 + y^2"))]
316+
#:label "z = x² + y²"))]
317+
318+
@history[#:changed "7.9" "Added support for pictures for #:label"]
299319
}
300320

301321
@defproc[(contour-intervals3d
@@ -314,15 +334,17 @@ For example,
314334
[#:contour-widths contour-widths (pen-widths/c (listof real?)) (contour-widths)]
315335
[#:contour-styles contour-styles (plot-pen-styles/c (listof real?)) (contour-styles)]
316336
[#:alphas alphas (alphas/c (listof ivl?)) (contour-interval-alphas)]
317-
[#:label label (or/c string? #f) #f]
337+
[#:label label (or/c string? pict? #f) #f]
318338
) renderer3d?]{
319339
Returns a renderer that plots contour intervals and contour lines on the surface of a function.
320340
The appearance keyword arguments are interpreted identically to the appearance keyword arguments to @(racket contour-intervals).
321341

322342
For example,
323343
@interaction[#:eval plot-eval (plot3d (contour-intervals3d (λ (x y) (+ (sqr x) (sqr y)))
324344
-1.1 1.1 -1.1 1.1
325-
#:label "z = x^2 + y^2"))]
345+
#:label "z = x² + y²"))]
346+
347+
@history[#:changed "7.9" "Added support for pictures for #:label"]
326348
}
327349

328350
@section{3D Isosurface Renderers}
@@ -339,7 +361,7 @@ For example,
339361
[#:line-width line-width (>=/c 0) (surface-line-width)]
340362
[#:line-style line-style plot-pen-style/c (surface-line-style)]
341363
[#:alpha alpha (real-in 0 1) (surface-alpha)]
342-
[#:label label (or/c string? #f) #f]
364+
[#:label label (or/c string? pict? #f) #f]
343365
) renderer3d?]{
344366
Returns a renderer that plots the surface of constant output value of the function @(racket f). The argument @(racket d) is the constant value.
345367

@@ -348,6 +370,8 @@ For example, a sphere is all the points in which the Euclidean distance function
348370
(λ (x y z) (sqrt (+ (sqr x) (sqr y) (sqr z)))) 1
349371
-1 1 -1 1 -1 1)
350372
#:altitude 25)]
373+
374+
@history[#:changed "7.9" "Added support for pictures for #:label"]
351375
}
352376

353377
@defproc[(isosurfaces3d
@@ -364,7 +388,7 @@ For example, a sphere is all the points in which the Euclidean distance function
364388
[#:line-widths line-widths (pen-widths/c (listof real?)) (isosurface-line-widths)]
365389
[#:line-styles line-styles (plot-pen-styles/c (listof real?)) (isosurface-line-styles)]
366390
[#:alphas alphas (alphas/c (listof real?)) (isosurface-alphas)]
367-
[#:label label (or/c string? #f) #f]
391+
[#:label label (or/c string? pict? #f) #f]
368392
) renderer3d?]{
369393
Returns a renderer that plots multiple isosurfaces. The appearance keyword arguments are interpreted similarly to those of @(racket contours).
370394

@@ -377,6 +401,8 @@ Use this to visualize functions from three inputs to one output; for example:
377401
#:z-min -2 #:z-max 2)]
378402

379403
If it helps, think of the output of @(racket f) as a density or charge.
404+
405+
@history[#:changed "7.9" "Added support for pictures for #:label"]
380406
}
381407

382408
@section{3D Rectangle Renderers}
@@ -392,7 +418,7 @@ If it helps, think of the output of @(racket f) as a density or charge.
392418
[#:line-width line-width (>=/c 0) (rectangle3d-line-width)]
393419
[#:line-style line-style plot-pen-style/c (rectangle-line-style)]
394420
[#:alpha alpha (real-in 0 1) (rectangle-alpha)]
395-
[#:label label (or/c string? #f) #f]
421+
[#:label label (or/c string? pict? #f) #f]
396422
) renderer3d?]{
397423
Returns a renderer that draws rectangles.
398424

@@ -415,6 +441,8 @@ This can be used to draw histograms; for example,
415441
(vector x-ivl y-ivl (ivl 0 z)))))
416442
#:alpha 3/4
417443
#:label "Appx. 2D Normal"))]
444+
445+
@history[#:changed "7.9" "Added support for pictures for #:label"]
418446
}
419447

420448
@defproc[(discrete-histogram3d
@@ -430,7 +458,7 @@ This can be used to draw histograms; for example,
430458
[#:line-width line-width (>=/c 0) (rectangle3d-line-width)]
431459
[#:line-style line-style plot-pen-style/c (rectangle-line-style)]
432460
[#:alpha alpha (real-in 0 1) (rectangle-alpha)]
433-
[#:label label (or/c string? #f) #f]
461+
[#:label label (or/c string? pict? #f) #f]
434462
[#:add-x-ticks? add-x-ticks? boolean? #t]
435463
[#:add-y-ticks? add-y-ticks? boolean? #t]
436464
[#:x-far-ticks? x-far-ticks? boolean? #f]
@@ -443,6 +471,8 @@ Missing pairs are not drawn; for example,
443471
(plot3d (discrete-histogram3d '(#(a a 1) #(a b 2) #(b b 3))
444472
#:label "Missing (b,a)"
445473
#:color 4 #:line-color 4))]
474+
475+
@history[#:changed "7.9" "Added support for pictures for #:label"]
446476
}
447477

448478
@defproc[(stacked-histogram3d

plot-lib/plot/private/common/legend.rkt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
;; Functions that create legend entries and lists of legend entries.
44

55
(require racket/class racket/match racket/list racket/string
6+
(only-in typed/pict pict)
67
"type-doc.rkt"
78
"math.rkt"
89
"format.rkt"
@@ -14,15 +15,15 @@
1415
;; ===================================================================================================
1516
;; Line legends
1617

17-
(:: line-legend-entry (-> String Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry))
18+
(:: line-legend-entry (-> (U String pict) Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry))
1819
(define (line-legend-entry label color width style)
1920
(legend-entry label (λ (pd x-size y-size)
2021
(define y (* 1/2 y-size))
2122
(send pd set-pen color width style)
2223
(send pd set-alpha 1)
2324
(send pd draw-line (vector (ann 0 Real) y) (vector x-size y)))))
2425

25-
(:: line-legend-entries (-> String (Listof Real) (Listof String)
26+
(:: line-legend-entries (-> (U String pict) (Listof Real) (Listof String)
2627
(Plot-Colors (Listof Real))
2728
(Pen-Widths (Listof Real))
2829
(Plot-Pen-Styles (Listof Real))
@@ -51,7 +52,7 @@
5152
;; ===================================================================================================
5253
;; Rectangle legends
5354

54-
(:: rectangle-legend-entry (-> String
55+
(:: rectangle-legend-entry (-> (U String pict)
5556
Plot-Color Plot-Brush-Style
5657
Plot-Color Nonnegative-Real Plot-Pen-Style
5758
legend-entry))
@@ -63,7 +64,7 @@
6364
(send pd draw-rect (vector (ivl 0 x-size) (ivl 0 y-size))))))
6465

6566
(:: rectangle-legend-entries
66-
(-> String (Listof Real)
67+
(-> (U String pict) (Listof Real)
6768
(Plot-Colors (Listof Real)) (Plot-Brush-Styles (Listof Real))
6869
(Plot-Colors (Listof Real)) (Pen-Widths (Listof Real)) (Plot-Pen-Styles (Listof Real))
6970
(Listof legend-entry)))
@@ -97,7 +98,7 @@
9798
;; ===================================================================================================
9899
;; Interval legends
99100

100-
(:: interval-legend-entry (-> String
101+
(:: interval-legend-entry (-> (U String pict)
101102
Plot-Color Plot-Brush-Style
102103
Plot-Color Nonnegative-Real Plot-Pen-Style
103104
Plot-Color Nonnegative-Real Plot-Pen-Style
@@ -123,7 +124,7 @@
123124
(vector x-size (ann 0 Real))))))
124125

125126
(:: interval-legend-entries
126-
(-> String (Listof ivl) (Listof String)
127+
(-> (U String pict) (Listof ivl) (Listof String)
127128
(Plot-Colors (Listof ivl)) (Plot-Brush-Styles (Listof ivl))
128129
(Plot-Colors (Listof ivl)) (Pen-Widths (Listof ivl)) (Plot-Pen-Styles (Listof ivl))
129130
(Plot-Colors (Listof ivl)) (Pen-Widths (Listof ivl)) (Plot-Pen-Styles (Listof ivl))
@@ -178,7 +179,7 @@
178179
;; ===================================================================================================
179180
;; Point legends
180181

181-
(:: point-legend-entry (-> String Point-Sym Plot-Color Plot-Color Nonnegative-Real Nonnegative-Real
182+
(:: point-legend-entry (-> (U String pict) Point-Sym Plot-Color Plot-Color Nonnegative-Real Nonnegative-Real
182183
legend-entry))
183184
(define (point-legend-entry label sym color fill-color size line-width)
184185
(legend-entry label (λ (pd x-size y-size)
@@ -188,7 +189,7 @@
188189
(send pd draw-glyphs
189190
(list (vector (* 1/2 x-size) (* 1/2 y-size))) sym size))))
190191

191-
(:: arrow-legend-entry (-> String Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry))
192+
(:: arrow-legend-entry (-> (U String pict) Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry))
192193
(define (arrow-legend-entry label color line-width line-style)
193194
(legend-entry label (λ (pd x-size y-size)
194195
(send pd set-pen color line-width line-style)

0 commit comments

Comments
 (0)