Timeline
Chart overview
Timelines display events or milestones arranged chronologically along a horizontal or vertical axis.
Key points
- They help visualize sequences, durations, and the relative timing of events, making them essential for project planning, historical analysis, and storytelling.
Python Tutorial
How to create a timeline in Python
Use the full tutorial for implementation details, troubleshooting, and chart variations in matplotlib, seaborn, and plotly.
Complete Guide to Scientific Data VisualizationExample Visualization

Create This Chart Now
Generate publication-ready timelines with AI in seconds. No coding required – just describe your data and let AI do the work.
View example prompt
"Create a horizontal timeline showing 'Key Milestones' for a software product launch spanning 12 months. Generate 10 milestone events: 'Kickoff Meeting' (Jan 5), 'Requirements Complete' (Jan 30), 'Architecture Approved' (Feb 15), 'Alpha Release' (Apr 1), 'Beta Testing Starts' (May 15), 'Security Audit' (Jun 10), 'Performance Optimization' (Jul 20), 'Release Candidate' (Aug 30), 'Documentation Complete' (Sep 15), 'Public Launch' (Oct 1). Alternate milestone labels above and below the timeline to prevent overlap. Color-code by phase: Planning (blue), Development (green), Testing (orange), Launch (red). Add vertical connectors from timeline to labels. Mark today's date with a vertical dashed line. Include month labels on the axis. Title: 'Product Launch Roadmap 2024'."
How to create this chart in 30 seconds
Upload Data
Drag & drop your Excel or CSV file. Plotivy securely processes it in your browser.
AI Generation
Our AI analyzes your data and generates the Timeline code automatically.
Customize & Export
Tweak the design with natural language, then export as high-res PNG, SVG or PDF.
Newsletter
Get one weekly tip for better timelines
Join researchers receiving concise Python plotting techniques to improve chart clarity and reduce revision cycles.
Python Code Example
# === IMPORTS ===
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime
# === USER-EDITABLE PARAMETERS ===
title = "Product Launch Roadmap 2024"
figsize = (14, 6)
# === EXAMPLE DATASET ===
milestones = [
('Kickoff Meeting', '2024-01-05', 'Planning', 'blue'),
('Requirements Complete', '2024-01-30', 'Planning', 'blue'),
('Architecture Approved', '2024-02-15', 'Planning', 'blue'),
('Alpha Release', '2024-04-01', 'Development', 'green'),
('Beta Testing Starts', '2024-05-15', 'Development', 'green'),
('Security Audit', '2024-06-10', 'Testing', 'orange'),
('Performance Optimization', '2024-07-20', 'Testing', 'orange'),
('Release Candidate', '2024-08-30', 'Testing', 'orange'),
('Documentation Complete', '2024-09-15', 'Launch', 'red'),
('Public Launch', '2024-10-01', 'Launch', 'red'),
]
df = pd.DataFrame(milestones, columns=['Event', 'Date', 'Phase', 'Color'])
df['Date'] = pd.to_datetime(df['Date'])
# Print summary
print("=== Product Launch Timeline ===")
print(f"\nTotal Milestones: {len(df)}")
print(f"Duration: {df['Date'].min().strftime('%b %d, %Y')} to {df['Date'].max().strftime('%b %d, %Y')}")
print(f"\nMilestones by Phase:")
for phase in df['Phase'].unique():
count = len(df[df['Phase'] == phase])
print(f" {phase}: {count} milestones")
# === CREATE TIMELINE ===
fig, ax = plt.subplots(figsize=figsize)
# Create the timeline axis
ax.axhline(y=0, color='gray', linewidth=2, alpha=0.5)
# Alternate label positions above/below
positions = [1 if i % 2 == 0 else -1 for i in range(len(df))]
# Plot milestones
for idx, (_, row) in enumerate(df.iterrows()):
pos = positions[idx]
# Marker on timeline
ax.scatter(row['Date'], 0, s=100, c=row['Color'], zorder=5, edgecolors='white', linewidth=2)
# Vertical connector
ax.plot([row['Date'], row['Date']], [0, pos * 0.4], color=row['Color'], linewidth=2)
# Label box
ax.annotate(
f"{row['Event']}\n{row['Date'].strftime('%b %d')}",
xy=(row['Date'], 0),
xytext=(row['Date'], pos * 0.5),
ha='center',
va='bottom' if pos > 0 else 'top',
fontsize=9,
fontweight='bold',
bbox=dict(boxstyle='round,pad=0.3', facecolor='white', edgecolor=row['Color'], alpha=0.9)
)
# Format x-axis
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
ax.set_xlim(datetime(2024, 1, 1), datetime(2024, 11, 1))
# Remove y-axis
ax.set_ylim(-1, 1)
ax.set_yticks([])
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# Add legend
from matplotlib.patches import Patch
legend_elements = [
Patch(facecolor='blue', label='Planning'),
Patch(facecolor='green', label='Development'),
Patch(facecolor='orange', label='Testing'),
Patch(facecolor='red', label='Launch')
]
ax.legend(handles=legend_elements, loc='upper right', framealpha=0.9)
plt.title(title, fontsize=16, fontweight='bold', pad=20)
plt.tight_layout()
plt.show()
# END-OF-CODE
Opens the Analyze page with this code pre-loaded and ready to execute
Console Output
=== Product Launch Timeline === Total Milestones: 10 Duration: Jan 05, 2024 to Oct 01, 2024 Milestones by Phase: Planning: 3 milestones Development: 2 milestones Testing: 3 milestones Launch: 2 milestones
Common Use Cases
- 1Project milestone tracking
- 2Historical events visualization
- 3Product roadmaps
- 4Biography timelines
Pro Tips
Alternate label positions for density
Use icons for event types
Add connecting lines for related events
Long-tail keyword opportunities
High-intent chart variations
Library comparison for this chart
matplotlib
Best when you need full control over axis formatting, annotation placement, and journal-specific styling for timeline.
Scientific Chart Selection Cheat Sheet
Not sure whether to use a Violin Plot, Box Plot, or Ridge Plot? Download our single-page reference mapping the most-used scientific chart types, exactly when to use them, and the core Matplotlib/Seaborn functions.