EchoTime Explainable time-series similarity for humans and agents.
Examples / Beginner example
Beginner example

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.

Question

Are Python and JavaScript attention curves moving together strongly enough to treat them as the same traffic story?

This example uses daily 2024 Wikipedia pageviews for Python and JavaScript. It is the same shape as a normal user workflow on their own CSV: one date column, two numeric columns, one call to compare_series(...), and then a rolling view if you want time-local context.

Input two numeric columns from one table Call compare_series(df['python_views'], df['javascript_views']) Output SimilarityReport + rolling windows
  1. Load the pageview table with pandas.
  2. Select the two columns you want to compare.
  3. Run compare_series(...) and optionally rolling_similarity(...) to see where the relationship changes.
Result at a glance
Pearson 0.75Spearman 0.86Mutual info 0.43Diff r 0.70
Component mean 0.75 across 5 time-series metrics

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.

spectral similarity0.93
trend similarity0.78
shape similarity0.72
derivative similarity0.70
Runnable example

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)})
What you should see

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.
Use your own data

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.
Python vs JavaScript
EchoTime series previewSeries previewPythonJavaScript

The daily pageview curves share broad shape, but the peaks and dips do not line up perfectly.

Similarity radar
Similarity radarSimilarity radarRadar over the time-series metrics. Read it together with Pearson, Spearman, and mutual info.ShapeDTWTrendDerivativeSpectral

The radar makes it obvious which kinds of agreement are strong and which are only moderate.

Rolling component mean
Rolling component meanRolling component meanmean=0.75, min=0.20, max=0.92 across per-window metric means

Rolling windows show when the average across the similarity metrics stays high and when the two topics separate.