Python and JavaScript pageviews move together, but not identically
A clean two-column workflow on real Wikimedia traffic data: read a table, compare two series, then inspect how the relationship changes over rolling windows.
Python pageviews vs JavaScript pageviews: Pearson r 0.75, Spearman rho 0.86, Kendall tau 0.70. The best agreement appears in spectral similarity and trend similarity.
This is the minimal script a human user would actually run: load data, call EchoTime, inspect the returned object.
from pathlib import Path
import pandas as pd
from echotime import compare_series, rolling_similarity
data_path = Path(__file__).resolve().parents[1] / "data" / "real_python_javascript_pageviews_2024.csv"
df = pd.read_csv(data_path)
report = compare_series(df["python_views"], df["javascript_views"], left_name="Python pageviews", right_name="JavaScript pageviews")
windows = rolling_similarity(df["python_views"], df["javascript_views"], window=28, step=7)
print(report.to_summary_card_markdown())
print({"rolling_windows": len(windows), "mean_similarity": round(report.similarity_score, 3)})
You should see high Pearson and Spearman agreement, with weaker local-change alignment than the broad attention trend.
# EchoTime similarity summary
**Compared:** Python pageviews vs JavaScript pageviews
## Headline
Python pageviews vs JavaScript pageviews: Pearson r 0.75, Spearman rho 0.86, Kendall tau 0.70. The best agreement appears in spectral similarity and trend similarity.
## Familiar statistics
| metric | value |
|---|---:|
| Pearson r | 0.745 |
| Spearman rho | 0.861 |
| Kendall tau | 0.699 |
| Best-lag Pearson r | 0.745 |
| Mutual info | 0.425 |
| First-difference r | 0.699 |
## Time-series-specific metrics
| plain-language label | score |
|---|---:|
| spectral similarity | 0.932 |
| trend similarity | 0.780 |
| shape similarity | 0.722 |
| derivative similarity | 0.699 |
## Recommended next actions
- Plot both series after z-score normalization to show the shared shape without scale differences.
- Run rolling or windowed similarity if you expect the relationship to change over time.
- Use structural-profile similarity when scales, frequencies, or observation modes differ too much for raw-shape comparison.
- Inspect spectral or seasonality-aware models because the two series share rhythm strongly.
- Pearson 0.75 / Spearman 0.86 / Mutual info 0.43 shows the curves move together, but the first-difference match is weaker than the broad trend.
- Trend agreement is stronger than spectral agreement, which means the shared direction is clearer than the fine-grained cadence.
- This is a real table you can inspect and swap out for your own CSV with almost no code changes.
This is the pattern most users will follow with their own CSV.
- Read your table with pandas, then pass the two numeric columns into compare_series(...).
- If your file also has dates, keep them for rolling plots or report annotations even if the basic comparison works without them.
- Write report.to_html_report() to disk when you need something you can hand to a teammate.
The daily pageview curves share broad shape, but the peaks and dips do not line up perfectly.
The radar makes it obvious which kinds of agreement are strong and which are only moderate.
Rolling windows show when the average across the similarity metrics stays high and when the two topics separate.