# Plots.jl with inset

**URL:** <https://discourse.julialang.org/t/plots-jl-with-inset/102936>\
**Category:** Visualization\
**Tags:** plots\
**Created:** [August 18, 2023, 9:09am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936 "2023-08-18T09:09:26Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [August 18, 2023, 9:09am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/1 "2023-08-18T09:09:26Z")

</div>

I’m trying to use Plots.jl with an _inset_. For simplicity, consider the plot

```julia
x=range(0,3pi/2,length=100)
plot(x,[sin.(x),sinc.(x)], label=["sin" "sinc"])

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/2/c24ce8735022a566ebb1c2baad54fa707820800f.png)

Suppose I want to insert an `inset` in the lower left corner of the plot with details of the same plot around the first crossing of the curves, i.e., ca. (x,y) ca = (0.6,0.5). So I want to replicate the same plot, say, with xlim changed to ca. xlim=(0.5,0.7) and ylim=(0.4,0.6) for the inset, and put it in the lower left corner.

How can I do that?

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [August 18, 2023, 9:30am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/2 "2023-08-18T09:30:05Z")

</div>

`inset_subplots` here: [Layouts · Plots](https://docs.juliaplots.org/latest/layouts/)

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [August 18, 2023, 3:14pm UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/3 "2023-08-18T15:14:59Z")

</div>

Thanks, I figured it out…

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/5/c5d0f5626120ab3e52a099acc5017ba9f39839eb.png)

It could have been simpler, but it works.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [August 18, 2023, 9:03pm UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/4 "2023-08-18T21:03:16Z")

</div>

Nice! Feel free to post any suggestions, recent frustration is a valuable resource 🙂

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [August 21, 2023, 7:47am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/5 "2023-08-21T07:47:51Z")

</div>

Sorry for (week-end) delay. Here is _more or less_ what I did (I don’t include all the code, just the essential parts).

### Here is what I did

Note: at the outset, I have already defined 3 functions: `uₒ`, `uₒ_c`, and `uₒ_` which depend on temperature in a temperature span `T_span`.

- I plot the “main plot”:

```julia
plot(T_span.-273.15,uₒ.(T_span),...)
plot!(T_span.-273.15,uₒ_c.(T_span),...
plot!(T_span.-273.15,uₒ_.(T_span),...)

```

- Next, I plot the _inset_:

```julia
plot!(
    T_span.-273.15, [uₒ.(T_span), uₒ_c.(T_span),uₒ_.(T_span)], ...
    xlim=(0,100),ylim=(1.165,1.192),
    frame=:box,
    yticks=false,
    inset=bbox(0.143,0.47,0.35,0.35),
    subplot=2
)

```

### Some “recent frustrations” and (unrealistic?) suggestions…

#### Things in documentation that confused me

1. At first, I didn’t know where to find the information in the documentation for Plots.jl.

If I search `Plots.jl` and open the

 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/d/ed490f133f2c4d6d5c9fd51e491b784501e9afe0.png)

page, attempt to find the `inset` information by:

- typing in `inset` in the search box – now luck

- do `Ctrl+f` in the browser, and searched for `inset`. Again, now luck, because the browser search function only search in the active window, i.e., in the `Tutorial` up until (but not including) `Series Types`.  

- your suggstion of `inset_subplots` helped somewhat, but what really helped is the link to `Layouts . Plots`.

Still, `inset_subplots` does not occur in the `plot` command… it is possible that `inset_subplots` _really_ means "the range of commands from `inset` to `subplot`?? That is, however, not obvious to me.

NOTE: this problem I have with search is not unique for `Plots.jl`.

1. Somewhat confusing argument list?

```julia
# The call is `bbox(x, y, width, height, origin...)`, where numbers are treated as
# "percent of parent"

```

This is somewhat confusing… the numbers (`x`, `y`, `width`, `height`) are not “percent of parent” (a number from 0-100), but _fraction_ of parent (range: 0-1).

So my understanding of these numbers are:

- `x`, `y` gives the coordinates of the inset relative to the upper left corner of the parent figure, which is position (0,0), with coordinate axes going downwards (`x`) and to the right ( `y`), and where the lower right corner of the parent plot is in position (1,1).

- `width`, `height` specify the width and height of the inset in _fraction_ of the parent plot window.

- Is it somewhat confusing the the first coordinate of `x`, `y` relates to the vertical position, while the first of `width`, `height` relates to _horizontal_ size? More logical with `x`, `y`, `height`, `width`? Perhaps.

- the `origin` argument is not really explained. But from examples, I _assume_ that it is possible with two arguments, and that the purpose is to define how the inset is positioned relative to the inset origin specified by `x`, `y`. Where the default is that the inset origin is the upper left corner of the inset, so possible `origin` commands are `:bottom`, `:right`, and similar.

1. What does the `subplot` command do? Do I _have_ to set the `subplot = 2` if I have a single parent plot, i.e., without subplots?

#### Could the inset work in a simpler way?

Perhaps. The `plot` command may get somewhat convoluted for complex plots with insets.

Would it be possible to do my plot above in the following way?

```julia
plot(T_span.-273.15,uₒ.(T_span),...)
plot!(T_span.-273.15,uₒ_c.(T_span),...
fig_parent = plot!(T_span.-273.15,uₒ_.(T_span),...)

```

followed by:

```julia
fig_sub = plot(T_span.-273.15, [uₒ.(T_span), uₒ_c.(T_span),uₒ_.(T_span)], ...
    xlim=(0,100),ylim=(1.165,1.192),
    frame=:box,
    yticks=false)

```

followed by:

```julia
plot!(fig_parent,
 fig_sub,
 inset=bbox(0.143,0.47,0.35,0.35),
 subplot=2

```

That way, the plot command holding the `inset` command itself becomes relatively simple, while it is still possible to created complex plots for the parent plot and the inset.

OK – I have no idea whether this is possible from the architecture of `Plots`…

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [August 21, 2023, 8:45am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/6 "2023-08-21T08:45:10Z")

</div>

> [@BLI](#):
>
> - typing in `inset` in the search box – now luck

Yes, this is unfortunate. It’s really difficult to make everything that’s possible also easily searchable, but this could definitely be improved in this case. We should consider having a header for “Inset plots”, because it’s not obvious that the fifth (or whatever) item in that list, “Layouts” is the correct one.

> [@BLI](#):
>
> but _fraction_ of parent

Yes, that’s a mistake. I think your understanding of the arguments to `bbox` are _nearly_ correct, but `x` goes from left to right and `y` goes from top to bottom, so they are in the same order as the `width`/`height` arguments. `origin` is poorly explained, I think a good solution would be to expand the docstring of `bbox` (which right now is pretty usesless).

> [@BLI](#):
>
> Do I _have_ to set the `subplot = 2`

Kind of, yes. This makes it so none of your keyword arguments affect the _parent_ subplot. Consider

```julia
plot([sin, cos])
plot!([sin, cos]; xlim=(-0.5,0.5), inset=bbox(0.2,0.2,0.3,0.3,:right))

```

and

```julia
plot([sin, cos])
plot!([sin, cos];xlim=(-0.5,0.5), inset=bbox(0.2,0.2,0.3,0.3,:right), subplot=2)

```

These two will be very similar, but in the former, the `xlim` kwarg also updates the xlims of the parent subplot, so both of them go from -0.5 to 0.5, while the latter has the parent going from -4.5 to 4.5 and the inset going from -0.5 to 0.5. This is not at all transparent, but possibly necessary for this to be a consistent interface (What if I _want_ to create an insert _and_ update the xlims in a single call, this is how I would expect to do so). Perhaps the solution here is to create an `inset!(parent, ...)` alias, where the parent is not affected by any of the kwargs. Worth considering.

I agree with your suggestion, to be able to place a Plot object in an inset. In fact, when searching to see if anyone else had a similar suggestion in the Plots github repo, [I found that _I_ had raised just such an issue a year ago](https://github.com/JuliaPlots/Plots.jl/issues/4066). I thought this sounded familiar. It should not be impossible to make one of these work.

Thank you for your comments! I hope the status quo is acceptable for now, I’ll try to make some time to make a PR at least fixing the documentation.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [August 21, 2023, 9:05am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/7 "2023-08-21T09:05:14Z")

</div>

Status quo is fine for now :-).

> but `x` goes from left to right and `y` goes from top to bottom

Argh. Of course.

---

<div class="post-metadata">

**Author:** ![Ayesha](https://avatars.discourse-cdn.com/v4/letter/a/c0e974/32.png) [@Ayesha](https://discourse.julialang.org/u/Ayesha)\
**Post date:** [February 8, 2024, 8:08am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/9 "2024-02-08T08:08:18Z")

</div>

Could you please share the code for making this plot? I have two plots defined as p1 and p2. I am trying to have a similar plot to the one shown here.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [February 8, 2024, 10:53am UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/10 "2024-02-08T10:53:32Z")

</div>

Assuming two plots, `p1` and `p2` – for illustration

```julia
x = range(0,2pi,length=100)
p1 = plot(x,sin)
p2 = plot(x,cos)

```

What I would have _liked_ is the following to work (but it doesn’t):

```julia
plot(p1)
plot!(p2,
    inset=bbox(0.15,0.45,0.35, 0.4),
    subplot=2
)

```

… the result is:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/8/b885957d30fd6e981b478357b3fabb4ff2f875ea.png)

It seems like it is necessary to create `p2` inside of the `plot` statement which has the `inset` statement:

```julia
plot(p1)
plot!(x, cos,
    inset=bbox(0.15,0.45,0.35, 0.4),
    subplot=2
)

```

which gives the desired result:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/3/f3b9fbe3efd0bcefaefb87abe8c673d34f51a6a9.png)

This lack of support for writing `plot!(p2, inset...)` is not a problem for a simple inset, but rather limiting for more complex insets.

I hope this answers your question.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [February 8, 2024, 12:06pm UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/12 "2024-02-08T12:06:01Z")

</div>

@rafael.guerra – did you delete your response?

Anyways, I got an e-mail copy of your suggestions, and it works! Nice! Here is how it can be done:

```julia
x = range(0,2pi,length=100)
p1 = plot(x,sin)

```

produces:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/a/8a921d0c8717f57a26f04317985bc751827beb5d.png)

Then do:

```julia
plot!(p1,
inset=bbox(0.15,0.45,0.35, 0.4),
    subplot=2)

```

leading to:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/3/73a3511b740fc4f95a1c1f1923fdf5bc910d0f05.png)

and finally:

```julia
plot!(p1[2],x,cos)
plot!(p1[2],x,sinc)

```

leads to:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/e/8e733dae449490c8ed28ab2030a4b731121ed802.png)

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [February 8, 2024, 12:39pm UTC](https://discourse.julialang.org/t/plots-jl-with-inset/102936/13 "2024-02-08T12:39:09Z")

</div>

Yes, the syntax is closer to what you wanted, but just using subplot=2 seems cleaner for this purpose.
