Skip to content

Commit ebeae83

Browse files
jeremymanningclaude
andcommitted
Final plot polish: viridis palette and robust legend suppression
- Add DEFAULT_LABEL_FONTSIZE (14) and apply to all plot axis labels - Use viridis color palette globally (sns.set_palette) - Update all axis labels and titles to sentence case - Capitalize 'Temporal' feature across egg.py, analysis.py, helpers.py - Convert all example egg files (cmr, frfr, murd62) to sentence case features - Rename FRFR conditions to sentence case with proper spacing - Rename "Length" condition to "Word length" in FRFR dataset - Add FRFR tutorial with viridis palette and condition ordering - Fix plot_type default to ensure legend suppression works reliably 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b66178c commit ebeae83

28 files changed

+1632
-53
lines changed
10.1 KB
Binary file not shown.
9.11 KB
Binary file not shown.
1.02 KB
Loading
658 KB
Loading
44.9 KB
Loading
54 Bytes
Loading
63.9 KB
Loading

docs/auto_examples/index.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,23 @@ Gallery of Examples
285285
</div>
286286

287287

288+
.. raw:: html
289+
290+
<div class="sphx-glr-thumbcontainer" tooltip="This example demonstrates analyzing the Feature-Rich Free Recall (FRFR) dataset, which investigates how different word features affect memory organization during free recall. The dataset contains 452 subjects across 11 experimental conditions, each varying which word features were made salient during encoding.">
291+
292+
.. only:: html
293+
294+
.. image:: /auto_examples/images/thumb/sphx_glr_plot_frfr_data_thumb.png
295+
:alt:
296+
297+
:ref:`sphx_glr_auto_examples_plot_frfr_data.py`
298+
299+
.. raw:: html
300+
301+
<div class="sphx-glr-thumbnail-title">Analyze Feature-Rich Free Recall (FRFR) Data</div>
302+
</div>
303+
304+
288305
.. thumbnail-parent-div-close
289306
290307
.. raw:: html
@@ -311,6 +328,7 @@ Gallery of Examples
311328
/auto_examples/fingerprint_optimalpresenter
312329
/auto_examples/plot_murdock_data
313330
/auto_examples/plot_cmr_data
331+
/auto_examples/plot_frfr_data
314332

315333

316334
.. only:: html

docs/auto_examples/plot_cmr_data.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"outputs": [],
1717
"source": [
18-
"# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nimport quail\nimport matplotlib.pyplot as plt\nimport warnings\n\n# Suppress RuntimeWarnings about empty slices (from subjects with fewer lists)\nwarnings.filterwarnings('ignore', category=RuntimeWarning)\n\n# Load the CMR dataset\negg = quail.load_example_data('cmr')\n\nprint(f\"Loaded CMR data: {egg.n_subjects} subjects, {egg.n_lists} lists, \"\n f\"{egg.list_length} items per list\")\n\n# Build per-subject listgroups: map each list to its condition\n# In this dataset, lists are mixed within subjects (each list has its own condition)\n# Use None for lists without valid condition data (they will be excluded from grouped analyses)\nlistgroup = []\nfor subj_idx in range(egg.n_subjects):\n subj_listgroup = []\n for list_idx in range(egg.n_lists):\n try:\n sample = egg.pres.loc[(subj_idx, list_idx)][0]\n if sample and 'condition' in sample:\n subj_listgroup.append(sample['condition'])\n else:\n # Use the same group name as valid lists to avoid separate \"Unknown\" category\n # These are likely practice/buffer lists\n subj_listgroup.append(None)\n except (KeyError, IndexError, TypeError):\n subj_listgroup.append(None)\n listgroup.append(subj_listgroup)\n\n# Count lists per condition (excluding None)\nfrom collections import Counter\nall_conditions = [c for subj in listgroup for c in subj if c is not None]\nprint(f\"Lists per condition: {dict(Counter(all_conditions))}\")\n\n# Create a figure with subplots for each analysis\nfig, axes = plt.subplots(2, 2, figsize=(12, 10))\n\n# 1. Probability of First Recall - use quail's built-in plot with error bars\npfr = egg.analyze('pfr', listgroup=listgroup)\npfr.plot(ax=axes[0, 0], plot_type='list', legend=True)\n\n# 2. Lag-CRP - use quail's built-in plot with error bars (legend=False)\nlagcrp = egg.analyze('lagcrp', listgroup=listgroup)\nlagcrp.plot(ax=axes[0, 1], plot_type='list', legend=False)\n\n# 3. Serial Position Curve - use quail's built-in plot with error bars (legend=False)\nspc = egg.analyze('spc', listgroup=listgroup)\nspc.plot(ax=axes[1, 0], plot_type='list', legend=False)\n\n# Configure PFR plot\naxes[0, 0].set_title('Probability of First Recall')\naxes[0, 0].set_xlabel('Serial Position')\naxes[0, 0].set_ylabel('Probability')\naxes[0, 0].set_ylim([0, 0.3])\n\n# Configure Lag-CRP plot\naxes[0, 1].set_title('Lag-CRP')\naxes[0, 1].set_xlabel('Lag')\naxes[0, 1].set_ylabel('Conditional Recall Probability')\naxes[0, 1].set_xlim([-10, 10])\naxes[0, 1].axvline(x=0, color='gray', linestyle='--', alpha=0.5)\n\n# Configure SPC plot\naxes[1, 0].set_title('Serial Position Curve')\naxes[1, 0].set_xlabel('Serial Position')\naxes[1, 0].set_ylabel('Recall Probability')\naxes[1, 0].set_ylim([0, 1])\n\n# 4. Memory Fingerprint - averaged across all lists\navg_listgroup = ['average'] * egg.n_lists\nfingerprint = egg.analyze('fingerprint', features=['task', 'temporal'],\n listgroup=avg_listgroup)\nfingerprint.plot(ax=axes[1, 1], title='Memory Fingerprint', ylim=[0, 1])\naxes[1, 1].set_xlabel('Feature')\naxes[1, 1].set_ylabel('Clustering Score')\n\nplt.tight_layout()\nplt.suptitle('Polyn et al. (2009) CMR Dataset Analysis', y=1.02, fontsize=14)\nplt.savefig('cmr_analysis.png', dpi=150, bbox_inches='tight')\nplt.show()\n\nprint(\"\\nAnalysis complete! Saved plot to cmr_analysis.png\")"
18+
"# Code source: Contextual Dynamics Laboratory\n# License: MIT\n\nfrom collections import Counter\n\nimport quail\nimport matplotlib.pyplot as plt\nimport warnings\n\n# Suppress RuntimeWarnings about empty slices (from subjects with fewer lists)\nwarnings.filterwarnings('ignore', category=RuntimeWarning)\n\n# Load the CMR dataset\negg = quail.load_example_data('cmr')\n\nprint(f\"Loaded CMR data: {egg.n_subjects} subjects, {egg.n_lists} lists, \"\n f\"{egg.list_length} items per list\")\n\n# Build per-subject listgroups: map each list to its condition\n# In this dataset, lists are mixed within subjects (each list has its own condition)\n# Use None for lists without valid condition data (they will be excluded from grouped analyses)\nlistgroup = []\nfor subj_idx in range(egg.n_subjects):\n subj_listgroup = []\n for list_idx in range(egg.n_lists):\n try:\n sample = egg.pres.loc[(subj_idx, list_idx)][0]\n if sample and 'condition' in sample:\n subj_listgroup.append(sample['condition'])\n else:\n # Use the same group name as valid lists to avoid separate \"Unknown\" category\n # These are likely practice/buffer lists\n subj_listgroup.append(None)\n except (KeyError, IndexError, TypeError):\n subj_listgroup.append(None)\n listgroup.append(subj_listgroup)\n\n# Count lists per condition (excluding None)\nall_conditions = [c for subj in listgroup for c in subj if c is not None]\nprint(f\"Lists per condition: {dict(Counter(all_conditions))}\")\n\n# Create a figure with subplots for each analysis\nfig, axes = plt.subplots(2, 2, figsize=(12, 10))\n\n# 1. Probability of First Recall - use quail's built-in plot with error bars\npfr = egg.analyze('pfr', listgroup=listgroup)\npfr.plot(ax=axes[0, 0], plot_type='list', legend=True)\n\n# 2. Lag-CRP - use quail's built-in plot with error bars (legend=False)\nlagcrp = egg.analyze('lagcrp', listgroup=listgroup)\nlagcrp.plot(ax=axes[0, 1], plot_type='list', legend=False)\n\n# 3. Serial Position Curve - use quail's built-in plot with error bars (legend=False)\nspc = egg.analyze('spc', listgroup=listgroup)\nspc.plot(ax=axes[1, 0], plot_type='list', legend=False)\n\n# Configure PFR plot\naxes[0, 0].set_title('Probability of First Recall')\naxes[0, 0].set_xlabel('Serial Position')\naxes[0, 0].set_ylabel('Probability')\naxes[0, 0].set_ylim([0, 0.3])\n\n# Configure Lag-CRP plot\naxes[0, 1].set_title('Lag-CRP')\naxes[0, 1].set_xlabel('Lag')\naxes[0, 1].set_ylabel('Conditional Recall Probability')\naxes[0, 1].set_xlim([-10, 10])\naxes[0, 1].axvline(x=0, color='gray', linestyle='--', alpha=0.5)\n\n# Configure SPC plot\naxes[1, 0].set_title('Serial Position Curve')\naxes[1, 0].set_xlabel('Serial Position')\naxes[1, 0].set_ylabel('Recall Probability')\naxes[1, 0].set_ylim([0, 1])\n\n# 4. Memory Fingerprint - averaged across all lists\navg_listgroup = ['average'] * egg.n_lists\nfingerprint = egg.analyze('fingerprint', features=['task', 'temporal'],\n listgroup=avg_listgroup)\nfingerprint.plot(ax=axes[1, 1], title='Memory Fingerprint', ylim=[0, 1])\naxes[1, 1].set_xlabel('Feature')\naxes[1, 1].set_ylabel('Clustering Score')\n\nplt.tight_layout()\nplt.suptitle('Polyn et al. (2009) CMR Dataset Analysis', y=1.02, fontsize=14)\nplt.savefig('cmr_analysis.png', dpi=150, bbox_inches='tight')\nplt.show()\n\nprint(\"\\nAnalysis complete! Saved plot to cmr_analysis.png\")"
1919
]
2020
}
2121
],

docs/auto_examples/plot_cmr_data.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
# Code source: Contextual Dynamics Laboratory
3131
# License: MIT
3232

33+
from collections import Counter
34+
3335
import quail
3436
import matplotlib.pyplot as plt
3537
import warnings
@@ -63,7 +65,6 @@
6365
listgroup.append(subj_listgroup)
6466

6567
# Count lists per condition (excluding None)
66-
from collections import Counter
6768
all_conditions = [c for subj in listgroup for c in subj if c is not None]
6869
print(f"Lists per condition: {dict(Counter(all_conditions))}")
6970

0 commit comments

Comments
 (0)