Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 52 additions & 4 deletions docs/plot_dataset/bubble.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ def generate_dataset_bubble(
log_y=True,
)

# ---------- Reference line, OLS fit, and arrow (all robust in log space)
numeric_x = pd.to_numeric(data[x_field], errors="coerce")
numeric_y = pd.to_numeric(data[y_field], errors="coerce")
mask = (
Expand All @@ -190,9 +191,29 @@ def generate_dataset_bubble(
log_x = np.log10(numeric_x[mask])
log_y = np.log10(numeric_y[mask])
ss_tot = np.sum((log_y - log_y.mean()) ** 2)

# Draw 1:1 line as an underlying shape, clipped to 10^0..10^4 and data bounds
lx_min = max(log_x.min(), log_y.min(), 0.0) # >= 10^0
lx_max = min(log_x.max(), log_y.max(), 4.0) # <= 10^4
if lx_min < lx_max:
x0 = 10**lx_min
x1 = 10**lx_max
fig.add_shape(
type="line",
x0=x0,
y0=x0,
x1=x1,
y1=x1,
xref="x",
yref="y",
layer="below",
line=dict(color="#9ca3af", width=1.5, dash="dash"),
)

# Red dotted OLS line (computed in log space), clipped to same bounds
if np.ptp(log_x) > 0 and np.ptp(log_y) > 0 and ss_tot > 0:
slope, intercept = np.polyfit(log_x, log_y, 1)
line_log_x = np.linspace(log_x.min(), log_x.max(), 200)
line_log_x = np.linspace(max(log_x.min(), 0.0), min(log_x.max(), 4.0), 200)
line_x = 10**line_log_x
line_y = 10 ** (slope * line_log_x + intercept)
fig.add_trace(
Expand All @@ -201,15 +222,40 @@ def generate_dataset_bubble(
y=line_y,
mode="lines",
name="log-log fit",
line=dict(color="#111827", width=2, dash="dot"),
line=dict(color="#dc2626", width=2, dash="dot"),
hoverinfo="skip",
showlegend=False,
opacity=0.35,
)
)
residuals = log_y - (slope * log_x + intercept)
r_squared = 1 - np.sum(residuals**2) / ss_tot
fit_annotation_text = f"log-log OLS fit R² = {r_squared:.3f}"
fit_annotation_text = f"<span style='color:#dc2626'>Red dotted line: log-log OLS fit R² = {r_squared:.3f}</span>"

# Arrow label ~60% along the 1:1 segment for stable placement
if lx_min < lx_max:
t = 0.82 # control the position along the line
annot_log = (1 - t) * lx_min + t * lx_max
annot_xy = np.log10(10**annot_log)
fig.add_annotation(
x=annot_xy,
y=annot_xy,
text="One record per subject",
showarrow=True,
arrowhead=3,
arrowsize=2,
arrowwidth=2,
arrowcolor="#6b7280",
ax=110,
ay=90,
axref="pixel",
ayref="pixel",
font=dict(size=20, color="#374151"),
align="left",
)

# ---------- Hover and styling ----------
x_hover, y_hover = _build_hover_template(x_field, y_field)
hover_template = (
"<b>%{customdata[0]}</b>"
f"<br>{x_hover}"
Expand Down Expand Up @@ -244,12 +290,14 @@ def generate_dataset_bubble(
margin=dict(l=60, r=40, t=80, b=60),
template="plotly_white",
legend=dict(
title="Modality",
title="Modality 🖱️ (click to toggle)",
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=0.99,
itemclick="toggle",
itemdoubleclick="toggleothers",
),
font=dict(
family="Inter, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif",
Expand Down
19 changes: 16 additions & 3 deletions docs/prepare_summary_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def wrap_dataset_name(name: str):
}

// 2) Initialize DataTable with SearchPanes button
const FILTER_COLS = [1,2,3,4,5,6];
const FILTER_COLS = [1,2,3,4,5,6,7];
// Detect the index of the size column by header text
const sizeIdx = (function(){
let idx = -1;
Expand Down Expand Up @@ -191,14 +191,14 @@ def wrap_dataset_name(name: str):

// 3) UX: click a header to open the relevant filter pane
$table.find('thead th').each(function (i) {
if ([1,2,3,4].indexOf(i) === -1) return;
if ([1,2,3,4,5].indexOf(i) === -1) return;
window.jQuery(this)
.css('cursor','pointer')
.attr('title','Click to filter this column')
.on('click', function () {
dataTable.button('.buttons-searchPanes').trigger();
window.setTimeout(function () {
const idx = [1,2,3,4].indexOf(i);
const idx = [1,2,3,4,5].indexOf(i);
const $container = window.jQuery(dataTable.searchPanes.container());
const $pane = $container.find('.dtsp-pane').eq(idx);
const $title = $pane.find('.dtsp-title');
Expand Down Expand Up @@ -234,6 +234,7 @@ def prepare_table(df: pd.DataFrame):
df = df[
[
"dataset",
"record_modality",
"n_records",
"n_subjects",
"n_tasks",
Expand All @@ -253,6 +254,7 @@ def prepare_table(df: pd.DataFrame):
"modality of exp": "modality",
"type of exp": "type",
"Type Subject": "pathology",
"record_modality": "record modality",
}
)
# number of subject are always int
Expand All @@ -270,6 +272,7 @@ def prepare_table(df: pd.DataFrame):
pathology_normalizer = _tag_normalizer("pathology")
modality_normalizer = _tag_normalizer("modality")
type_normalizer = _tag_normalizer("type")
record_modality_normalizer = _tag_normalizer("record_modality")

df["pathology"] = df["pathology"].apply(
lambda value: wrap_tags(
Expand All @@ -292,6 +295,13 @@ def prepare_table(df: pd.DataFrame):
normalizer=type_normalizer,
)
)
df["record modality"] = df["record modality"].apply(
lambda value: wrap_tags(
value,
kind="dataset-record-modality",
normalizer=record_modality_normalizer,
)
)

# Creating the total line
df.loc["Total"] = df.sum(numeric_only=True)
Expand All @@ -301,6 +311,7 @@ def prepare_table(df: pd.DataFrame):
df.loc["Total", "pathology"] = ""
df.loc["Total", "modality"] = ""
df.loc["Total", "type"] = ""
df.loc["Total", "record modality"] = ""
df.loc["Total", "size"] = human_readable_size(df.loc["Total", "size_bytes"])
df = df.drop(columns=["size_bytes"])
# arrounding the hours
Expand Down Expand Up @@ -361,11 +372,13 @@ def main(source_dir: str, target_dir: str):
"pathology": "Pathology",
"modality": "Modality",
"type": "Type",
"record modality": "Record modality",
}
)
df = df[
[
"Dataset",
"Record modality",
"Pathology",
"Modality",
"Type",
Expand Down
Binary file added docs/source/_static/eeg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/_static/emg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/_static/ieeg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading