如何使用 Matplotlib 从预渲染图像创建子图
How to create subplot from prerendered image with Matplotlib
objective 是根据某个程序生成的图形列表创建一个子图。
此处,单个图像由函数 plot_conn()
生成,并附加在 all_fig
中
最终,我想将这些图绘制成如下所示:
Matplotlib
或任何其他 Python 软件包是否可行?
这 3 个数字是使用下面的代码生成的,并列在 all_figure
下
import numpy as np
import mne
from mne.connectivity import spectral_connectivity
from mne.viz import circular_layout, plot_connectivity_circle
import matplotlib.pyplot as plt
def generate_conn():
# Generate data
label_names = ['FP1', 'FP2', 'F3', 'F4', 'F7', 'F8', 'C3', 'C4',
'T3', 'T4', 'O1', 'O2']
np.random.seed ( 42 )
n_epochs = 5
n_channels = len(label_names)
n_times = 1000
data = np.random.rand ( n_epochs, n_channels, n_times )
# Set sampling freq
sfreq = 250 # A reasonable random choice
# 10Hz sinus waves with random phase differences in each channel and epoch
# Generate 10Hz sinus waves to show difference between connectivity
# over time and over trials. Here we expect con over time = 1
for i in range ( n_epochs ):
for c in range ( n_channels ):
wave_freq = 10
epoch_len = n_times / sfreq
# Introduce random phase for each channel
phase = np.random.rand ( 1 ) * 10
# Generate sinus wave
x = np.linspace ( -wave_freq * epoch_len * np.pi + phase,
wave_freq * epoch_len * np.pi + phase, n_times )
data [i, c] = np.squeeze ( np.sin ( x ) )
info = mne.create_info(ch_names=label_names,
ch_types=['eeg'] * len(label_names),
sfreq=sfreq)
epochs = mne.EpochsArray(data, info)
# Define freq bands
Freq_Bands = {"delta": [1.25, 4.0],
"theta": [4.0, 8.0],
"alpha": [8.0, 13.0],
"beta": [13.0, 30.0],
"gamma": [30.0, 49.0]}
n_freq_bands = len ( Freq_Bands )
# Convert to tuples for the mne function
fmin = tuple ( [list ( Freq_Bands.values () ) [f] [0] for f in range ( len ( Freq_Bands ) )] )
fmax = tuple ( [list ( Freq_Bands.values () ) [f] [1] for f in range ( len ( Freq_Bands ) )] )
# Connectivity methods
connectivity_methods = ["plv"]
n_con_methods = len ( connectivity_methods )
# # Calculate PLV and wPLI - the MNE python implementation is over trials
con, freqs, times, n_epochs, n_tapers = spectral_connectivity (
epochs, method=connectivity_methods,
mode="multitaper", sfreq=sfreq, fmin=fmin, fmax=fmax,
faverage=True, verbose=0 )
all_ch=epochs.ch_names
return con,all_ch
def plot_conn(conmat,all_ch):
lh_labels = ['FP1', 'F7', 'F3', 'C3', 'T3', 'O1']
rh_labels = ['FP2', 'F8', 'F4', 'C4', 'T4', 'O2']
node_order = lh_labels +rh_labels # Is this order tally with the con arrangement?
node_angles = circular_layout ( all_ch, node_order, start_pos=90,
group_boundaries=[0, len ( all_ch) // 2] )
fig = plt.figure ( num=None, figsize=(8, 8), facecolor='black' )
fig=plot_connectivity_circle ( conmat, all_ch, n_lines=300,
node_angles=node_angles,
title='All-to-All Connectivity '
'Condition (PLI)_Delta', fig=fig )
return fig
con,all_ch=generate_conn()
all_fig=[]
for idx in range (0,3):
conmat = con [:, :, idx]
fig=plot_conn(conmat,all_ch)
all_fig.append(fig)
如有任何提示,我将不胜感激。
其中一个肮脏的解决方案是将每个 Figure
转换为 Numpy array
,然后垂直或水平堆叠数组。
- 生成
Numpy array
- 使用
canvas.draw ()
重新绘制plot_connectivity_circle
输出
- 使用
np.frombuffer
变换新的重绘图像得到数组形式
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
canvas = FigureCanvas ( fig )
plot_connectivity_circle ( conmat, all_ch, n_lines=300,
node_angles=node_angles,
title=f'All-to-All Connectivity_ band_{bands}', fig=fig )
canvas.draw ()
s, (width, height) = canvas.print_to_buffer ()
im0 = np.frombuffer ( s, np.uint8 ).reshape ( (height, width, 4) )
- 通过堆叠数组创建子图
np.hstack ( all_fig ) # all_fig is a list of array
完整代码如下:
import mne
from mne.connectivity import spectral_connectivity
from mne.viz import circular_layout, plot_connectivity_circle
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
def generate_conn ():
# Generate data
label_names = ['FP1', 'FP2', 'F3', 'F4', 'F7', 'F8', 'C3', 'C4',
'T3', 'T4', 'O1', 'O2']
np.random.seed ( 42 )
n_epochs = 5
n_channels = len ( label_names )
n_times = 1000
data = np.random.rand ( n_epochs, n_channels, n_times )
# Set sampling freq
sfreq = 250 # A reasonable random choice
# 10Hz sinus waves with random phase differences in each channel and epoch
# Generate 10Hz sinus waves to show difference between connectivity
# over time and over trials. Here we expect con over time = 1
for i in range ( n_epochs ):
for c in range ( n_channels ):
wave_freq = 10
epoch_len = n_times / sfreq
# Introduce random phase for each channel
phase = np.random.rand ( 1 ) * 10
# Generate sinus wave
x = np.linspace ( -wave_freq * epoch_len * np.pi + phase,
wave_freq * epoch_len * np.pi + phase, n_times )
data [i, c] = np.squeeze ( np.sin ( x ) )
info = mne.create_info ( ch_names=label_names,
ch_types=['eeg'] * len ( label_names ),
sfreq=sfreq )
epochs = mne.EpochsArray ( data, info )
# Define freq bands
Freq_Bands = {"delta": [1.25, 4.0],
"theta": [4.0, 8.0],
"alpha": [8.0, 13.0],
"beta": [13.0, 30.0],
"gamma": [30.0, 49.0]}
n_freq_bands = len ( Freq_Bands )
# Convert to tuples for the mne function
fmin = tuple ( [list ( Freq_Bands.values () ) [f] [0] for f in range ( len ( Freq_Bands ) )] )
fmax = tuple ( [list ( Freq_Bands.values () ) [f] [1] for f in range ( len ( Freq_Bands ) )] )
# Connectivity methods
connectivity_methods = ["plv"]
n_con_methods = len ( connectivity_methods )
# # Calculate PLV and wPLI - the MNE python implementation is over trials
con, freqs, times, n_epochs, n_tapers = spectral_connectivity (
epochs, method=connectivity_methods,
mode="multitaper", sfreq=sfreq, fmin=fmin, fmax=fmax,
faverage=True, verbose=0 )
all_ch = epochs.ch_names
return con, all_ch
def plot_conn (conmat, all_ch, idx, bands):
lh_labels = ['FP1', 'F7', 'F3', 'C3', 'T3', 'O1']
rh_labels = ['FP2', 'F8', 'F4', 'C4', 'T4', 'O2']
node_order = lh_labels + rh_labels # Is this order tally with the con arrangement?
node_angles = circular_layout ( all_ch, node_order, start_pos=90,
group_boundaries=[0, len ( all_ch ) // 2] )
fig = plt.figure ( num=None, figsize=(8, 8), facecolor='black' )
canvas = FigureCanvas ( fig )
plot_connectivity_circle ( conmat, all_ch, n_lines=300,
node_angles=node_angles,
title=f'All-to-All Connectivity_ band_{bands}', fig=fig )
canvas.draw ()
s, (width, height) = canvas.print_to_buffer ()
im0 = np.frombuffer ( s, np.uint8 ).reshape ( (height, width, 4) )
return im0
con, all_ch = generate_conn ()
all_fig = [plot_conn ( con [:, :, idx], all_ch, idx, band ) for idx, band in enumerate ( ["delta", "theta", "alpha"] )]
SUBPLOT = np.hstack ( all_fig )
plt.imsave ( 'myimage.png', SUBPLOT )
objective 是根据某个程序生成的图形列表创建一个子图。
此处,单个图像由函数 plot_conn()
生成,并附加在 all_fig
最终,我想将这些图绘制成如下所示:
Matplotlib
或任何其他 Python 软件包是否可行?
这 3 个数字是使用下面的代码生成的,并列在 all_figure
import numpy as np
import mne
from mne.connectivity import spectral_connectivity
from mne.viz import circular_layout, plot_connectivity_circle
import matplotlib.pyplot as plt
def generate_conn():
# Generate data
label_names = ['FP1', 'FP2', 'F3', 'F4', 'F7', 'F8', 'C3', 'C4',
'T3', 'T4', 'O1', 'O2']
np.random.seed ( 42 )
n_epochs = 5
n_channels = len(label_names)
n_times = 1000
data = np.random.rand ( n_epochs, n_channels, n_times )
# Set sampling freq
sfreq = 250 # A reasonable random choice
# 10Hz sinus waves with random phase differences in each channel and epoch
# Generate 10Hz sinus waves to show difference between connectivity
# over time and over trials. Here we expect con over time = 1
for i in range ( n_epochs ):
for c in range ( n_channels ):
wave_freq = 10
epoch_len = n_times / sfreq
# Introduce random phase for each channel
phase = np.random.rand ( 1 ) * 10
# Generate sinus wave
x = np.linspace ( -wave_freq * epoch_len * np.pi + phase,
wave_freq * epoch_len * np.pi + phase, n_times )
data [i, c] = np.squeeze ( np.sin ( x ) )
info = mne.create_info(ch_names=label_names,
ch_types=['eeg'] * len(label_names),
sfreq=sfreq)
epochs = mne.EpochsArray(data, info)
# Define freq bands
Freq_Bands = {"delta": [1.25, 4.0],
"theta": [4.0, 8.0],
"alpha": [8.0, 13.0],
"beta": [13.0, 30.0],
"gamma": [30.0, 49.0]}
n_freq_bands = len ( Freq_Bands )
# Convert to tuples for the mne function
fmin = tuple ( [list ( Freq_Bands.values () ) [f] [0] for f in range ( len ( Freq_Bands ) )] )
fmax = tuple ( [list ( Freq_Bands.values () ) [f] [1] for f in range ( len ( Freq_Bands ) )] )
# Connectivity methods
connectivity_methods = ["plv"]
n_con_methods = len ( connectivity_methods )
# # Calculate PLV and wPLI - the MNE python implementation is over trials
con, freqs, times, n_epochs, n_tapers = spectral_connectivity (
epochs, method=connectivity_methods,
mode="multitaper", sfreq=sfreq, fmin=fmin, fmax=fmax,
faverage=True, verbose=0 )
all_ch=epochs.ch_names
return con,all_ch
def plot_conn(conmat,all_ch):
lh_labels = ['FP1', 'F7', 'F3', 'C3', 'T3', 'O1']
rh_labels = ['FP2', 'F8', 'F4', 'C4', 'T4', 'O2']
node_order = lh_labels +rh_labels # Is this order tally with the con arrangement?
node_angles = circular_layout ( all_ch, node_order, start_pos=90,
group_boundaries=[0, len ( all_ch) // 2] )
fig = plt.figure ( num=None, figsize=(8, 8), facecolor='black' )
fig=plot_connectivity_circle ( conmat, all_ch, n_lines=300,
node_angles=node_angles,
title='All-to-All Connectivity '
'Condition (PLI)_Delta', fig=fig )
return fig
con,all_ch=generate_conn()
all_fig=[]
for idx in range (0,3):
conmat = con [:, :, idx]
fig=plot_conn(conmat,all_ch)
all_fig.append(fig)
如有任何提示,我将不胜感激。
其中一个肮脏的解决方案是将每个 Figure
转换为 Numpy array
,然后垂直或水平堆叠数组。
- 生成
Numpy array
- 使用
canvas.draw ()
重新绘制 - 使用
np.frombuffer
变换新的重绘图像得到数组形式
plot_connectivity_circle
输出
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
canvas = FigureCanvas ( fig )
plot_connectivity_circle ( conmat, all_ch, n_lines=300,
node_angles=node_angles,
title=f'All-to-All Connectivity_ band_{bands}', fig=fig )
canvas.draw ()
s, (width, height) = canvas.print_to_buffer ()
im0 = np.frombuffer ( s, np.uint8 ).reshape ( (height, width, 4) )
- 通过堆叠数组创建子图
np.hstack ( all_fig ) # all_fig is a list of array
完整代码如下:
import mne
from mne.connectivity import spectral_connectivity
from mne.viz import circular_layout, plot_connectivity_circle
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
def generate_conn ():
# Generate data
label_names = ['FP1', 'FP2', 'F3', 'F4', 'F7', 'F8', 'C3', 'C4',
'T3', 'T4', 'O1', 'O2']
np.random.seed ( 42 )
n_epochs = 5
n_channels = len ( label_names )
n_times = 1000
data = np.random.rand ( n_epochs, n_channels, n_times )
# Set sampling freq
sfreq = 250 # A reasonable random choice
# 10Hz sinus waves with random phase differences in each channel and epoch
# Generate 10Hz sinus waves to show difference between connectivity
# over time and over trials. Here we expect con over time = 1
for i in range ( n_epochs ):
for c in range ( n_channels ):
wave_freq = 10
epoch_len = n_times / sfreq
# Introduce random phase for each channel
phase = np.random.rand ( 1 ) * 10
# Generate sinus wave
x = np.linspace ( -wave_freq * epoch_len * np.pi + phase,
wave_freq * epoch_len * np.pi + phase, n_times )
data [i, c] = np.squeeze ( np.sin ( x ) )
info = mne.create_info ( ch_names=label_names,
ch_types=['eeg'] * len ( label_names ),
sfreq=sfreq )
epochs = mne.EpochsArray ( data, info )
# Define freq bands
Freq_Bands = {"delta": [1.25, 4.0],
"theta": [4.0, 8.0],
"alpha": [8.0, 13.0],
"beta": [13.0, 30.0],
"gamma": [30.0, 49.0]}
n_freq_bands = len ( Freq_Bands )
# Convert to tuples for the mne function
fmin = tuple ( [list ( Freq_Bands.values () ) [f] [0] for f in range ( len ( Freq_Bands ) )] )
fmax = tuple ( [list ( Freq_Bands.values () ) [f] [1] for f in range ( len ( Freq_Bands ) )] )
# Connectivity methods
connectivity_methods = ["plv"]
n_con_methods = len ( connectivity_methods )
# # Calculate PLV and wPLI - the MNE python implementation is over trials
con, freqs, times, n_epochs, n_tapers = spectral_connectivity (
epochs, method=connectivity_methods,
mode="multitaper", sfreq=sfreq, fmin=fmin, fmax=fmax,
faverage=True, verbose=0 )
all_ch = epochs.ch_names
return con, all_ch
def plot_conn (conmat, all_ch, idx, bands):
lh_labels = ['FP1', 'F7', 'F3', 'C3', 'T3', 'O1']
rh_labels = ['FP2', 'F8', 'F4', 'C4', 'T4', 'O2']
node_order = lh_labels + rh_labels # Is this order tally with the con arrangement?
node_angles = circular_layout ( all_ch, node_order, start_pos=90,
group_boundaries=[0, len ( all_ch ) // 2] )
fig = plt.figure ( num=None, figsize=(8, 8), facecolor='black' )
canvas = FigureCanvas ( fig )
plot_connectivity_circle ( conmat, all_ch, n_lines=300,
node_angles=node_angles,
title=f'All-to-All Connectivity_ band_{bands}', fig=fig )
canvas.draw ()
s, (width, height) = canvas.print_to_buffer ()
im0 = np.frombuffer ( s, np.uint8 ).reshape ( (height, width, 4) )
return im0
con, all_ch = generate_conn ()
all_fig = [plot_conn ( con [:, :, idx], all_ch, idx, band ) for idx, band in enumerate ( ["delta", "theta", "alpha"] )]
SUBPLOT = np.hstack ( all_fig )
plt.imsave ( 'myimage.png', SUBPLOT )