Plot: how to insert plot in plot

The question is simple - how can I put a small figure inside the field of another one? Like this:


I read all info about Plot module, but I did not find a solution. But this type of figure with an insert is very common.

2 Likes

One thing to consider is using pict combinators from racket/pict to combine the plots after you generate them with plot-pict.

2 Likes

There are a few ways of doing it, and perhaps the simplest option for static plots (i.e. ones that will be printed or published) is to use the pict package. You can also save the picts to bitmaps or SVG files.

Here is an example:

#lang racket
(require plot pict)
(define outer-plot (plot-pict (function values 0 1) #:width 800 #:height 200))
(define inner-plot
  (parameterize ([plot-background "lightyellow"])
    (plot-pict (function sin -10 10) #:width 150 #:height 100)))

;; Simple super-imposition
(lt-superimpose outer-plot (inset inner-plot 60 10))

;; This version places the inner plot precisely in the top-left corner or the
;;  inner plot, that is at the  (0, 1) coordinate
(match-define (vector dc-x dc-y) ((plot-pict-plot->dc outer-plot) #(0 1)))
(pin-over outer-plot dc-x dc-y inner-plot)

4 Likes

Thank you. It works well. But,

  1. latex-pict does not work for labels. I used #:x-label (tex-math "a\ (nm)" #:scale 5), but with plot-pict there is nothing without an error.
  2. The (plot-new-window? #t) has no influence. The figure can not be shown in a separate window.
  3. How can I save in pdf file? The option #:out-file does not work.
2 Likes

@JoePass

ad 1. latex-pict does not work for labels.

It does actually - but admittedly it's a bit confusing when latex-pict used in DrRacket.

When DrRacket renders picts it doesn't show what latex-pict draws.
To see the labels inside DrRacket while you are working on it use (pict->bitmap your-pict).
There is no latex-pict problems when rendering picts to bitmaps, svg or pdfs.

Now the reason for this oddity is that latex-pict works by drawing directly into a cairo context (it calls a pdf renderer called Poppler to draw the label). Given a real cairo context everything works great (so bitmaps, svg and pdf work). DrRacket on the other hand
renders picts in a two-step process. First it renders the pict to a recording context.
That recording operations is then used to draw in the interaction window. I believe this approach to make it impossible for faulty user libraries to break the DrRacket repl.

The problem lies in the recording of the drawing operations. The recording done by record-dc% objects can only record drawing operations made to a drawing context dc% in the Racket level. Since latex-pict uses Poppler the drawing operations done by Poppler are simply not recorded. The effect in your case is that the pict looks normal in the repl - but all labels are missing.

Unfortunately I don't know how to implement a better solution. Maybe if record-dc% had an "convert cairio recording context to Racket drawing operations" it would be possible for latex-pict to tell the recording context what Poppler was drawing?

4 Likes

There is an save-pict-as-pdf in metapict/save-pdf.

3 Likes

Well, another option for "plot inside plot" is to use point-pict, this will allow you to open the plot in a new window and also use #:out-file.

Alex.

#lang racket
(require plot pict)
(plot-new-window? #t) 
(define inner-plot
  (parameterize ([plot-background "lightyellow"])
    (plot-pict (function sin -10 10) #:width 150 #:height 100)))

(plot (list (function values 0 1)
            (point-pict #(0 1) inner-plot #:point-sym 'none #:anchor 'top-left)))
3 Likes

Thank you, it works well. Now I have all that I need to make plots for papers. For scientific publication, in fact, one needs for simple possibilities. The documentation of the racket is very well but it is very huge and detailed. I guess that it will be very useful to make short addition for documentation about plot figures which contained a few examples.

1 Like

O, yes, another possibility. I used point-pict to add labels for figures, like a), b), but I did not guess to use a plot instead of a label. Good idea, thank you. Thanks to the community of this forum. Here, I obtained help for all my problems.

3 Likes

That's a great point. I wish there were a good place in the docs for examples like this. I just took a quick look, though, and it's really not clear that there's a good place for this. Or, more specifically, a place where people who need it would be likely to find it.

2 Likes

Perhaps add an appendix called examples like in metapict or sketching. Shouldn’t be too hard to do and I’m sure the maintainers would appreciate it.

https://docs.racket-lang.org/metapict/index.html#(part._examples)

https://soegaard.github.io/sketching/Examples.html

2 Likes

The plot package already contains examples for every type of plot. Documentation can always be improved, but I think the problem here is that the plot package is composable and is integrated well with the other libraries such as pict and the draw library. This is normally a great thing, but it is a problem for new users, since they expect a specific function for every feature they could possibly want.

For example, presumably the author searched the documentation for "plot inside plot", and even though they knew that one can create a plot as a pict using plot-pict and one can place any pict on a plot using point-pict, it did not occur to them to combine the two to place a plot inside a plot.

What could be done is a "cookbook" style documentation/website, where specific examples are added, similar to what matplotlib does: Examples — Matplotlib 3.5.1 documentation. However I don't have time to start and maintain such a project. For my part, I wrote several plot-related blog posts, to illustrate its flexibility, and I might add some more examples in the future there. I will also attempt to answer specific examples when people ask for these types of questions on the forums.

Alex.

5 Likes