# Access matplotlib/PyPlot object of Plots.jl plot

**URL:** <https://discourse.julialang.org/t/access-matplotlib-pyplot-object-of-plots-jl-plot/74422>\
**Category:** Visualization\
**Tags:** pyplot, pycall, plots\
**Created:** [January 11, 2022, 7:15pm UTC](https://discourse.julialang.org/t/access-matplotlib-pyplot-object-of-plots-jl-plot/74422 "2022-01-11T19:15:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tfiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tfiers/32/32427_2.png) [@tfiers](https://discourse.julialang.org/u/tfiers)\
**Post date:** [January 11, 2022, 7:15pm UTC](https://discourse.julialang.org/t/access-matplotlib-pyplot-object-of-plots-jl-plot/74422/1 "2022-01-11T19:15:45Z")

</div>

I plot `using Plots; pyplot()`

How can I access the created `PyPlot.Figure(PyObject <Figure size 640x480 with 1 Axes>)` and `PyObject <AxesSubplot:>` ? (I can get those when I use PyPlot directly, but then I’m not using Plots).

`Plots.PyPlot.gcf()` gives an empty (i.e. new) figure, so I suspect Plots closes the figure…

(pinging @daschw @isentropic).

---

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [January 12, 2022, 5:53am UTC](https://discourse.julialang.org/t/access-matplotlib-pyplot-object-of-plots-jl-plot/74422/2 "2022-01-12T05:53:26Z")

</div>

```julia
p = plot(rand(10));
p.o
# PyPlot.Figure(PyObject <Figure size 600x400 with 1 Axes>)

```

---

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [January 12, 2022, 5:54am UTC](https://discourse.julialang.org/t/access-matplotlib-pyplot-object-of-plots-jl-plot/74422/3 "2022-01-12T05:54:55Z")

</div>

you can modify p.o via pyplot standard pyplot API to further tweak the figure to your liking. I use this sometimes to add further minor tweaks (make sure not to use plots API, as it would replot it and erase your modifications)

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [January 15, 2022, 8:01pm UTC](https://discourse.julialang.org/t/access-matplotlib-pyplot-object-of-plots-jl-plot/74422/4 "2022-01-15T20:01:31Z")

</div>

It’s not entirely trivial to _modify_ the `.o` attribute containing the `PyPlot` figure in such a way that the changes can be written out to a file.

I’ve found the following to work:

```julia
using Plots
pyplot()

function plot_sine_curve(;kwargs...)
    # just for example...
    fig = plot(sin; kwargs...)
    return fig
end

function adjust_figure(fig)
    pyfig = fig.o
    ax = pyfig[:axes][1]
    ax.set_position([0.2, 0.2, 0.4, 0.4])
    ax.set_xlabel("new x label")
    return pyfig
end

fig = plot_sine_curve()
Plots.prepare_output(fig) # XXX
pyfig = adjust_figure(fig)
pyfig.savefig("out.pdf")

```

Note the line `Plots.prepare_output(fig)`! Without this, `fig.o[:axes]` will be empty. The `prepare_output` function is not part of the official Plots API, so this might be subject to change.

Instead of `prepare_output`, it would also work to run `savefig(fig, "out.pdf")` (which calls `prepare_output` internally). In that case, we would save the original Plots.jl-generated figure first, and then overwrite it with the “patched” version.

It is also important to point out that once you go to down to the pyplot level, you can’t go back up to the Plots.jl level for that figure. Hence, after `adjust_figure`, we call the lower-level `savefig` method of the `PyPlot.Figure`, not the high-level `Plots.savefig` method (which would write the original unmodified figure)
