Created
January 24, 2021 20:29
-
-
Save RuKrei/5262770d5bf2d2d3a78decb22190a152 to your computer and use it in GitHub Desktop.
MWE copypaster: plotly to mne.Report()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Thank you all for looking into this. | |
What I am working on here is a pipeline to aid in diagnosis of epilepsy in a clinical setting (Long term video EEG monitoring). | |
The goal is to extract Annotations of an EEG-file and visualize them in a useful manner. | |
The number of Annotations might be anything between only a few to a few hundred. Data should be visualized and also shown in | |
tabular form. | |
Plotly is an obvious choice, since its defaults handle this dynamic setting well. | |
I copypasted some parts of the code in order to reproduce a visualization from the pipeline. | |
""" | |
import mne | |
from mne import Report | |
import matplotlib.pyplot as plt | |
import pandas as pd | |
import numpy as np | |
import plotly.graph_objects as go | |
from plotly.subplots import make_subplots | |
# helper funcitons | |
def generate_random_events(tmin, tmax, nr_events=100): | |
# simulate extracted Events from raw file | |
type = ["e-", "s-", "t-"] | |
side = ["-l", "-r", "-b"] | |
e_names = ["Theta", "Suppression", "Something_frontal", "Something_temporal", "Something_parietal", | |
"Spikes", "Delta", "Shrap waves", "Beta", "Evolution"] | |
s_names = ["Figure4", "Jerks", "Numbness", "Arrest", "OAA", "Hypermotor", "Alien limb", | |
"Fumbling", "Version", "Head turn"] | |
t_name = "TestEvent" | |
time_from_onset = np.random.randint(tmin, tmax, nr_events) | |
time_from_onset.reshape(1,-1) | |
description = [] | |
for i in range(nr_events): | |
t = np.random.randint(3, size=1) | |
s = np.random.randint(3, size=1) | |
n = np.random.randint(10, size=1) | |
if str(type[t[0]]) == "e-": | |
de = str(type[t[0]]) + str(e_names[n[0]]) + str(side[s[0]]) | |
elif str(type[t[0]]) == "s-": | |
de = str(type[t[0]]) + str(s_names[n[0]]) + str(side[s[0]]) | |
else: | |
de = str(type[t[0]]) + t_name + str(side[s[0]]) | |
description.append(de) | |
return (description, time_from_onset) | |
def generate_df_with_pseudoevents(tmin, tmax, nr_events=150, source=None): | |
# put events into pd.DataFrame | |
description, time_from_onset = generate_random_events(tmin=tmin, tmax=tmax, nr_events=nr_events) | |
pseudoevents = dict() | |
pseudoevents["description"] = description | |
pseudoevents["time_from_onset"] = time_from_onset | |
df = pd.DataFrame(pseudoevents) | |
df.loc[:, "source"] = source | |
cols = list(df) | |
cols.insert(0, cols.pop(cols.index('source'))) | |
df = df.loc[:, cols] | |
return df | |
def extract_ordered_groups(df, edf="df"): | |
df = df.drop_duplicates(subset=["description"], keep="first") | |
print(f"\nThe following Event-Groups were extracted from the file {edf}\n\n\n") | |
e_events = df[df["description"].str.startswith("e-")] | |
e_events["order_of_occurence"] = (np.arange(len(e_events.axes[0])) +1).astype(int) | |
print("EEG-Events: \n\n", e_events, "\n\n") | |
s_events = df[df["description"].str.startswith("s-")] | |
s_events["order_of_occurence"] = (np.arange(len(s_events.axes[0])) +1).astype(int) | |
print("Semiology-Events: \n\n", s_events, "\n\n") | |
t_events = df[~df["description"].str.startswith("s-")] | |
t_events = t_events[~df["description"].str.startswith("e-")] | |
t_events["order_of_occurence"] = (np.arange(len(t_events.axes[0])) +1).astype(int) | |
print("Clinical Testing - Events: \n\n", t_events, "\n\n") | |
return e_events, s_events, t_events | |
def plot_interactive_subplot_with_table(df=None, eeg=None, semio=None, testing=None, title=None): | |
xaxis_title="Time in seconds (from seizure onset)" | |
fig = make_subplots(rows=5, cols=1, shared_xaxes="all", | |
specs=[[{"type": "table"}], | |
[{"type": "scatter"}], | |
[{"type": "scatter"}], | |
[{"type": "scatter"}], | |
[{"type": "scatter"}]], | |
subplot_titles=("Events", "EEG", "Semiology", "Testing", "All events"), | |
row_width=[0.1, 0.1, 0.1, 0.1, 0.8]) | |
# Add traces | |
# data | |
fig.add_trace(go.Table( | |
header=dict( | |
values=df.columns[:], font=dict(size=10)), | |
cells=dict( | |
values=[df[i].tolist() for i in df.columns[:]], | |
align="left") | |
), | |
row=1, col=1) | |
# scatter plots | |
x_axis = df["time_from_onset"] | |
y_axis = np.ones_like(x_axis) | |
# eeg | |
times, labels = extract_lab_sec(eeg) | |
fig.add_trace(go.Scatter(x=times, y=y_axis, | |
mode='markers', #mode="markers+text" | |
hoverinfo="name+x+text", | |
name='EEG', | |
text=labels, | |
marker_symbol="diamond"), row=2, col=1) | |
# semio | |
times, labels = extract_lab_sec(semio) | |
fig.add_trace(go.Scatter(x=times, y=y_axis, | |
mode='markers', | |
name='Semiology', | |
text=labels, | |
marker_symbol="x"), row=3, col=1) | |
# testing | |
times, labels = extract_lab_sec(testing) | |
fig.add_trace(go.Scatter(x=times, y=y_axis, | |
mode='markers', | |
name='Testing', | |
text=labels, | |
marker_symbol="circle"), row=4, col=1) | |
# grand average | |
times, labels = extract_lab_sec(df) | |
fig.add_trace(go.Scatter(x=times, y=y_axis, | |
mode='markers', | |
name='All events', | |
text=labels, | |
marker_symbol="hexagon2-open-dot"), row=5, col=1) | |
fig.update_layout(title=title, yaxis_title="") | |
fig.update_xaxes(rangeslider={"visible":True}, title={"text":xaxis_title}, row=5) | |
fig.update_yaxes(visible=False, showticklabels=False) | |
fig.update_layout(width=1200, height=1000) | |
return fig | |
def extract_lab_sec(df): | |
times = df["time_from_onset"] | |
labels = df["description"] | |
return times, labels | |
# ------------------------------------------------------------------ | |
# main part | |
df1 = generate_df_with_pseudoevents(tmin=-20, tmax=90, nr_events=300, source="df1") | |
e_events, s_events, t_events = extract_ordered_groups(df1, edf="df1") | |
fig = plot_interactive_subplot_with_table(df1, e_events, s_events, t_events, title="Random events") | |
# show figure? | |
fig.show() | |
# report | |
report = Report(subject="Test Subject", title="Event summary") | |
# add to report - non of them work | |
fig.to_html("fig.html") | |
report.add_htmls_to_section("fig.html", section="test", captions="test_add_htmls") | |
report.add_custom_css(fig) | |
report.save("Report.html") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment