# How to add mne plot to another subplot

**URL:** <https://mne.discourse.group/t/how-to-add-mne-plot-to-another-subplot/4866>\
**Category:** Support & Discussions\
**Tags:** visualization\
**Created:** [May 13, 2022, 5:59am UTC](https://mne.discourse.group/t/how-to-add-mne-plot-to-another-subplot/4866 "2022-05-13T05:59:10Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![balandongiv](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/balandongiv/32/104_2.png) [@balandongiv](https://mne.discourse.group/u/balandongiv)\
**Post date:** [May 13, 2022, 5:59am UTC](https://mne.discourse.group/t/how-to-add-mne-plot-to-another-subplot/4866/1 "2022-05-13T05:59:10Z")

</div>

The objective is to create subplot that consist

1. Line plot
2. raw data plot with annotation

The expected output is as shown the figure below

 ![mne](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/c/cddc25baa923598be9ad86099add4eaff8c481c0.jpeg)

The line plot can be easily created by simply passing the axes parameter

```python
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(9, 10))

ax1 = fig.add_subplot(2, 1, 1)
ax1.plot(range(10))

```

However, I am having difficulties in subploting the row plot since `mne.io.Raw.plot` does not accept `axes`

```python
import os

import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(sample_data_folder, 'MEG', 'sample',
                                    'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(sample_data_raw_file, verbose=False)
picks = mne.pick_channels_regexp(raw.ch_names, regexp='EEG 05.')
fig=raw.plot(order=picks, n_channels=len(picks))

```

While it is possible to first save locally `fig.savefig()` and append the raw.plot into the subplot as below

```python
sub1 = fig.add_subplot(2, 1, 2)

    image2 = cv.imread()
    sub1.imshow(image2, 'gray')

```

But, this is inefficient for multiple plotting.

So, my question is, is there better workaround to append the raw.plot onto a subplot without first need to save locally the fig?

---

<div class="post-metadata">

**Author:** ![cbrnr](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/cbrnr/32/1409_2.png) [@cbrnr](https://mne.discourse.group/u/cbrnr)\
**Post date:** [May 13, 2022, 6:29am UTC](https://mne.discourse.group/t/how-to-add-mne-plot-to-another-subplot/4866/2 "2022-05-13T06:29:17Z")

</div>

I don’t know the answer, but I’m interested to learn if this is possible. `Raw.plot()` returns a `Figure` consisting of multiple `Axes`, so I guess the first step would be to select the one you want. However, it doesn’t seem to be easily possible to move an `Axes` from one `Figure` to another from what I’ve seen in a quick Google search, so your solution is already pretty cool.

---

<div class="post-metadata">

**Author:** ![balandongiv](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/balandongiv/32/104_2.png) [@balandongiv](https://mne.discourse.group/u/balandongiv)\
**Post date:** [May 13, 2022, 5:48pm UTC](https://mne.discourse.group/t/how-to-add-mne-plot-to-another-subplot/4866/3 "2022-05-13T17:48:44Z")

</div>

Another alternative is to utilise the `CanvasAgg` backend directly to create image and extract this image to `numpy` array, which can in turn be passed off to `matplotlib`

First create the raw plot and expect an input in the form of `MNEBrowseFigure`

`fig_raw=raw.plot(order=picks, show=False, n_channels=len(picks))`

A canvas must be manually attached to the figure (pyplot would automatically do it). This is done by instantiating the canvas with the figure as argument.

`canvas = FigureCanvasAgg(fig)`

Retrieve a memory view on the renderer buffer, and convert it to a numpy array. There are two options to do this.

Option 1

```python
canvas.draw ()
img = np.asarray(canvas.buffer_rgba())

```

Option 2

```python
canvas.draw ()
img = np.asarray(canvas.buffer_rgba())
s, (width, height) = canvas.print_to_buffer ()
img = np.frombuffer ( s, np.uint8 ).reshape ( (height, width, 4) )

```

and pass it to `matplotlib`

```python
sub1 = fig.add_subplot(2, 1, 2)
sub1.imshow(img)

```

This will output

![Snap 2022-05-14 at 01.46.44](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/5/50abb87446494b602cb0ec1a204212fe7ff9f3a3.png)

Reference  
[https://matplotlib.org/3.5.0/gallery/user\_interfaces/canvasagg.html](https://matplotlib.org/3.5.0/gallery/user_interfaces/canvasagg.html)

Full code to reproduce the above figure

```python
import os

import matplotlib.pyplot as plt
import mne
import numpy as np
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

fig = plt.figure(figsize=(9, 10))

ax1 = fig.add_subplot(2, 1, 1)
ax1.plot(range(10))

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(sample_data_folder, 'MEG', 'sample',
                                    'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(sample_data_raw_file, verbose=False)
picks = mne.pick_channels_regexp(raw.ch_names, regexp='EEG 05.')
fig_raw=raw.plot(order=picks, show=False, n_channels=len(picks))

canvas = FigureCanvas (fig_raw)
canvas.draw ()

img = np.asarray(canvas.buffer_rgba())
sub1 = fig.add_subplot(2, 1, 2)
sub1.imshow(img)
plt.show()

```

---

<div class="post-metadata">

**Author:** ![richard](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/richard/32/15_2.png) [@richard](https://mne.discourse.group/u/richard)\
**Post date:** [May 13, 2022, 7:27pm UTC](https://mne.discourse.group/t/how-to-add-mne-plot-to-another-subplot/4866/4 "2022-05-13T19:27:06Z")

</div>

I think another more or less straightforward approach is simply plotting to the Agg backend, extracting the figures as NumPy arrays, and then concatenating those:

> <https://stackoverflow.com/questions/70083434/combine-two-matplotlib-figures-side-by-side-high-quality/70093661#70093661>
