autoreject / autoreject

Automated rejection and repair of bad trials/sensors in M/EEG
https://autoreject.github.io
BSD 3-Clause "New" or "Revised" License
138 stars 58 forks source link

RejectLog.plot() compressed along channels dimension with large number of trials #295

Closed aaronjnewman closed 1 year ago

aaronjnewman commented 1 year ago

Given an Epochs object containing 750 epochs (or another with 3600), the result of the following code

reject_log = ar.get_reject_log(epochs)
fig = reject_log.plot('horizontal')

produces a plot which is very wide, but compressed vertically such that the individual channels, and channel labels, are illegible. Varying the y parameter of the figure size has no effect on the height of the plot, nor does reducing the number of electrode labels, e.g.,:

fig, ax = plt.subplots(figsize=(12, 20))
reject_log.plot(orientation='horizontal', show_names=32, ax=ax)

I tried editing the plot code in autoreject.py to not draw the legend, which had no effect. Reducing the font size in line 1325 plt.setp(ax.get_yticklabels(), fontsize=4) did help a little, but the plots are still only slightly longer along the channels axis than before.

Previous experience with these plots (using data with ~300 epochs) didn't yield this problem - the aspect ratio was nice and figsize worked as expected - and I confirmed in the same script I'm working on that if I use only the first 300 epochs to fit AutoReject, the plots still work fine with the same data. So it seems to be an effect of a larger number of trials.

I will note that I'm working in a Jupyter notebook, which may contribute to the problem, but one would hope there would be a way to address it.

thanks in advance, Aaron image

jasmainak commented 1 year ago

Hi @aaronjnewman , thanks for the report. I tried the following to reproduce:

import numpy as np
import matplotlib.pyplot as plt

from autoreject import RejectLog

n_channels = 64
n_epochs = 3600
percent_bad_epochs = 0.1

ch_names = [f'EEG0{idx:02d}' for idx in range(n_channels)]
bad_epochs = np.random.rand(n_epochs) < percent_bad_epochs

labels = np.random.rand(n_epochs, n_channels) 
labels[labels >= percent_bad_epochs * 2] = 2
labels[labels < percent_bad_epochs] = 0
labels[(labels != 0) & (labels != 2)] = 1

reject_log = RejectLog(bad_epochs, labels, ch_names)
reject_log.plot(orientation='horizontal')

It seems that the passing aspect_ratio='auto' to plt.imshow would fix the problem.

image

Do you think this would be an acceptable solution?

aaronjnewman commented 1 year ago

Awesome, thanks @jasmainak. I added aspect='auto' to the ax.imshow comments in the plot method and got appropriate aspect ratios consistent with your example (see below). So this seems like an acceptable solution. Cheers!

image