Track changes in sentiment over narrative time.
Project description
Track changes in sentiment over the course of a narrative text. Inspired by Matthew Jockers’ syuzhet R package, moodswing brings sentiment trajectory analysis to Python with both dictionary-based and neural approaches.
moodswing helps you:
📊 Visualize emotional arcs in novels, memoirs, and other narratives
📚 Use proven lexicons (Syuzhet, AFINN, Bing, NRC) optimized for different text types
🧠 Leverage spaCy models for context-aware sentiment analysis
🔬 Apply DCT smoothing to reveal underlying narrative structure
🎨 Create publication-ready plots with flexible visualization options
Based on research in computational literary analysis, this package makes it easy to uncover the emotional patterns that shape stories.
Quick Start
Install from PyPI:
pip install moodswing
For spaCy support (optional):
pip install moodswing
python -m spacy download en_core_web_sm
Example: Analyze a Novel
from moodswing import (
DictionarySentimentAnalyzer,
Sentencizer,
DCTTransform,
prepare_trajectory,
plot_trajectory,
)
from moodswing.data import load_sample_text
# Load a sample novel
doc_id, text = load_sample_text("madame_bovary")
# Split into sentences
sentences = Sentencizer().split(text)
# Score each sentence
analyzer = DictionarySentimentAnalyzer()
scores = analyzer.sentence_scores(sentences, method="syuzhet")
# Create smoothed trajectory
trajectory = prepare_trajectory(
scores,
rolling_window=int(len(scores) * 0.1),
dct_transform=DCTTransform(low_pass_size=10, output_length=200, scale_range=True)
)
# Plot the emotional arc
plot_trajectory(trajectory, title="Madame Bovary: Sentiment Trajectory")
Features
- Four Sentiment Lexicons
Syuzhet: Optimized for narrative analysis
AFINN: Includes slang and informal language
Bing: Binary positive/negative classification
NRC: Multi-dimensional emotions (joy, fear, anger, etc.) with multilingual support
- Two Analysis Approaches
Dictionary-based: Fast, transparent word lookup
spaCy-based: Context-aware neural models (handles negation, sarcasm)
- Advanced Smoothing
Rolling mean: Local trend smoothing
DCT (Discrete Cosine Transform): Reveals overall narrative shape
Compatible with R’s syuzhet package for reproducible research
- Flexible Visualization
Built-in plotting with customizable colors and components
Export to pandas DataFrame for seaborn, plotly, or custom plots
Publication-ready output with figure size/DPI control
Documentation
Full documentation with tutorials, examples, and API reference:
📖 https://browndw.github.io/moodswing/
Get Started: Complete walkthrough with scholarly background
Using Sentiment Lexicons: Compare and choose the right dictionary
Using spaCy: Context-aware analysis with neural models
Visualization Guide: Custom plotting and styling
Examples Gallery: Ready-to-use code for common tasks
Technical Notes: DCT mathematics and R compatibility
API Reference: Complete function documentation
Citation
If you use this package in your research, please cite:
@software{moodswing2025,
author = {Brown, David},
title = {moodswing: Sentiment Trajectory Analysis for Python},
year = {2025},
url = {https://github.com/browndw/moodswing}
}
This package is based on Matthew Jockers’ syuzhet R package:
@article{jockers2015syuzhet,
title={Revealing sentiment and plot arcs with the Syuzhet package},
author={Jockers, Matthew L},
year={2015}
}
License
Code licensed under MIT License.
See LICENSE file.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file moodswing-0.1.0.tar.gz.
File metadata
- Download URL: moodswing-0.1.0.tar.gz
- Upload date:
- Size: 3.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d4664e729e267599dd7280ccf314d1505061456af795be2458bff967e6cc6c0
|
|
| MD5 |
877c73e9231e4b2b64766ba851a3648c
|
|
| BLAKE2b-256 |
16902b83ac12a03bed9c92a7dc4369164ddb59632d5154466c0757be95f15d72
|
Provenance
The following attestation bundles were made for moodswing-0.1.0.tar.gz:
Publisher:
ci.yml on browndw/moodswing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
moodswing-0.1.0.tar.gz -
Subject digest:
1d4664e729e267599dd7280ccf314d1505061456af795be2458bff967e6cc6c0 - Sigstore transparency entry: 798915684
- Sigstore integration time:
-
Permalink:
browndw/moodswing@80df1499a353c1b47d82e0d3c1af88f212db8dd1 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/browndw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@80df1499a353c1b47d82e0d3c1af88f212db8dd1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file moodswing-0.1.0-py3-none-any.whl.
File metadata
- Download URL: moodswing-0.1.0-py3-none-any.whl
- Upload date:
- Size: 3.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bba070fa30a97c09b1ae903adbbe6b6f0f219e68666b2430aeb10b40c25f03d
|
|
| MD5 |
82534b263104aea194e96eab0a01d307
|
|
| BLAKE2b-256 |
140823644ce5a2949738d5b00dfb08481fc09c5f93a4d218ea5914eb4da84793
|
Provenance
The following attestation bundles were made for moodswing-0.1.0-py3-none-any.whl:
Publisher:
ci.yml on browndw/moodswing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
moodswing-0.1.0-py3-none-any.whl -
Subject digest:
4bba070fa30a97c09b1ae903adbbe6b6f0f219e68666b2430aeb10b40c25f03d - Sigstore transparency entry: 798915686
- Sigstore integration time:
-
Permalink:
browndw/moodswing@80df1499a353c1b47d82e0d3c1af88f212db8dd1 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/browndw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@80df1499a353c1b47d82e0d3c1af88f212db8dd1 -
Trigger Event:
push
-
Statement type: