π§© Data Shape for Fixed-Point & Relative-Time Visualizations
π From Wide β Long in Pythonβ
When your computed dataset looks like this:
| fed_event_date | n_plus_1 | n_plus_2 | n_plus_5 |
|---|---|---|---|
| 2025-10-29 | 0.3% | 0.7% | 1.9% |
| 2025-11-13 | -0.2% | 0.4% | 1.1% |
β¦you can reshape it into a long format that Tableau (and any tidy-data workflow) will love.
import pandas as pd
# Example input: wide format
wide = pd.DataFrame({
"fed_event_date": ["2025-10-29", "2025-11-13"],
"n_plus_1": [0.3, -0.2],
"n_plus_2": [0.7, 0.4],
"n_plus_5": [1.9, 1.1],
})
# Melt the wide columns into long form
long = wide.melt(
id_vars=["fed_event_date"], # columns to keep
var_name="horizon_label", # name of the new "dimension" column
value_name="return" # name of the measure column
)
# Optionally extract numeric horizon (e.g. 1, 2, 5)
long["rel_horizon"] = long["horizon_label"].str.extract(r"(\d+)").astype(int)
print(long)
Output:
| fed_event_date | horizon_label | return | rel_horizon |
|---|---|---|---|
| 2025-10-29 | n_plus_1 | 0.3 | 1 |
| 2025-10-29 | n_plus_2 | 0.7 | 2 |
| 2025-10-29 | n_plus_5 | 1.9 | 5 |
| 2025-11-13 | n_plus_1 | -0.2 | 1 |
| 2025-11-13 | n_plus_2 | 0.4 | 2 |
| 2025-11-13 | n_plus_5 | 1.1 | 5 |
Now Tableau can use:
rel_horizon(orhorizon_label) as the X-axisreturnas the Y-axisfed_event_dateas the Color or Detail dimension.
1οΈβ£ The Guiding Principleβ
Data meant to be visualized should be long, not wide. Each thing you want to put on an axis should be a dimension, and each thing you want to aggregate should be a measure.
2οΈβ£ Why Wide Data Happensβ
Wide tables are a computational artifact, not an analytical design. They emerge naturally from:
- Vectorized calculations (
shift(-1),shift(-5), etc.) - Spreadsheet habits (one column per metric)
- Human readability (βI want to see everything for one event in one rowβ)
In other words: wide is for computation or inspection β not for visualization.
3οΈβ£ Why Long Is the Correct Shape for Visualizationβ
When you pivot from wide β long, youβre really expressing a semantic truth:
βN+1,β βN+2,β βN+5,β etc. are values of a single conceptual variable: time since event.
That variable β call it horizon or rel_time β belongs on the X-axis.
Your measure (like return) belongs on the Y-axis.
Tableau will then:
- Aggregate
returnbyhorizon - Draw continuous lines
- Let you filter, color, or facet by any other dimension (e.g.
fed_event_date)
4οΈβ£ In Practiceβ
| fed_event_date | horizon | return |
|---|---|---|
| 2025-10-29 | N+1 | 0.3% |
| 2025-10-29 | N+2 | 0.7% |
| 2025-10-29 | N+5 | 1.9% |
| 2025-11-13 | N+1 | -0.2% |
| 2025-11-13 | N+2 | 0.4% |
X-axis: horizon
Y-axis: return
Color: fed_event_date
Every line shares a fixed origin (N=0) β perfect for event studies, cumulative performance charts, or time-relative comparisons.
5οΈβ£ When (Rarely) Wide Makes Senseβ
There are only a few edge cases where you might intentionally keep wide data for visualization:
- Static metric tables / KPI dashboards
- Correlation matrices (when each column is an axis of the grid)
- Parallel coordinates plots
Everything else β especially time-based or event-based visuals β belongs in long form.
π§ Rule of Thumbβ
If you find yourself renaming columns just to plot them, your data should probably be long instead of wide.
π¨ Even Grids Are Longβ
Even visuals that look like wide data β such as heat maps β are conceptually long underneath.
πΉ What people think a heat map isβ
| N+1 | N+2 | N+3 | |
|---|---|---|---|
| Event A | 0.2 | 0.5 | 0.8 |
| Event B | 0.1 | 0.4 | 0.7 |
That looks like a 2D matrix, but Tableau still wants one row per cell, not one row per event:
| event | horizon | return |
|---|---|---|
| A | N+1 | 0.2 |
| A | N+2 | 0.5 |
| A | N+3 | 0.8 |
| B | N+1 | 0.1 |
| B | N+2 | 0.4 |
| B | N+3 | 0.7 |
eventβ Rowshorizonβ Columnsreturnβ Color
Even though it renders as a grid, itβs still a long-form dataset.
πΉ The conceptual ruleβ
Any time you have two things you want to cross on a grid, those two are dimensions, not measures. Measures fill the cells; dimensions define the grid.
π Converting Back: Long β Wideβ
Sometimes youβll want to pivot back into a wide form β for example, when exporting Tableau results or doing additional vectorized calculations.
# Starting from the "long" dataframe above
wide_again = long.pivot(
index="fed_event_date", # unique key or grouping column
columns="horizon_label", # dimension to expand into columns
values="return" # measure to fill cells
).reset_index()
# Optional: remove the pivot MultiIndex that Pandas creates
wide_again.columns.name = None
print(wide_again)
Output:
| fed_event_date | n_plus_1 | n_plus_2 | n_plus_5 |
|---|---|---|---|
| 2025-10-29 | 0.3 | 0.7 | 1.9 |
| 2025-11-13 | -0.2 | 0.4 | 1.1 |
This restores the original computational layout, ready for analysis or export.
π§ Summaryβ
| Concept | Wide Format | Long Format |
|---|---|---|
| Purpose | Computation / readability | Visualization / aggregation |
| Structure | One row per event | One row per (event, horizon) |
| Tool Compatibility | Spreadsheets, NumPy, SQL | Tableau, Power BI, analytics tools |
| Best For | Calculations | Charts, heatmaps, interactivity |
πͺ In Plain Englishβ
The moment you decide something belongs on an axis or label β itβs a dimension. Everything left over becomes a measure.