Smooth Curves and Curve Interpolation
Observable Plot supports various curve interpolation methods for line and area marks. This guide demonstrates all available curve types and when to use each one.
Linear Curves (Default)
Straight Line Segments
The default curve connects points with straight lines:
data:
source: |
[
{"x": 0, "y": 20},
{"x": 1, "y": 35},
{"x": 2, "y": 25},
{"x": 3, "y": 45},
{"x": 4, "y": 30},
{"x": 5, "y": 50}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: linear
stroke: steelblue
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 4
fill: steelblueWhen to Use:
- Default behavior (no curve specified)
- Sharp transitions are meaningful
- Minimal smoothing desired
- Performance-critical applications
Step Curves
Step After
Creates horizontal then vertical segments (step-after):
data:
source: |
[
{"time": 0, "value": 10},
{"time": 1, "value": 25},
{"time": 2, "value": 20},
{"time": 3, "value": 40},
{"time": 4, "value": 35}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: time
y: value
curve: step-after
stroke: darkorange
strokeWidth: 2
- type: dot
configuration:
x: time
y: value
r: 3
fill: darkorangeUse Cases:
- Digital signals
- State changes
- Inventory levels
- Constant value between observations
Step Before
Creates vertical then horizontal segments (step-before):
data:
source: |
[
{"time": 0, "value": 10},
{"time": 1, "value": 25},
{"time": 2, "value": 20},
{"time": 3, "value": 40},
{"time": 4, "value": 35}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: time
y: value
curve: step-before
stroke: purple
strokeWidth: 2
- type: dot
configuration:
x: time
y: value
r: 3
fill: purpleUse Cases:
- Leading indicators
- Future projections
- Forward-looking data
Step (Middle)
Creates steps centered on data points:
data:
source: |
[
{"time": 0, "value": 10},
{"time": 1, "value": 25},
{"time": 2, "value": 20},
{"time": 3, "value": 40},
{"time": 4, "value": 35}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: time
y: value
curve: step
stroke: green
strokeWidth: 2
- type: dot
configuration:
x: time
y: value
r: 3
fill: greenUse Cases:
- Centered step functions
- Histogram-like line charts
- Categorical transitions
Smooth Curves
Basis Spline
Creates smooth B-spline curves:
data:
source: |
[
{"x": 0, "y": 20},
{"x": 1, "y": 35},
{"x": 2, "y": 25},
{"x": 3, "y": 45},
{"x": 4, "y": 30},
{"x": 5, "y": 50}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: basis
stroke: "#e74c3c"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 3
fill: "#e74c3c"Characteristics:
- Very smooth curves
- May not pass through control points
- Good for general smoothing
- Creates aesthetically pleasing curves
Cardinal Spline
Creates interpolated curves with adjustable tension:
data:
source: |
[
{"x": 0, "y": 20},
{"x": 1, "y": 35},
{"x": 2, "y": 25},
{"x": 3, "y": 45},
{"x": 4, "y": 30},
{"x": 5, "y": 50}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: cardinal
stroke: "#9b59b6"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 3
fill: "#9b59b6"Characteristics:
- Passes through all data points
- Smooth interpolation
- Adjustable tension parameter
- Good balance of smoothness and accuracy
Catmull-Rom Spline
Creates smooth curves passing through all points:
data:
source: |
[
{"x": 0, "y": 20},
{"x": 1, "y": 35},
{"x": 2, "y": 25},
{"x": 3, "y": 45},
{"x": 4, "y": 30},
{"x": 5, "y": 50}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: catmull-rom
stroke: "#3498db"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 3
fill: "#3498db"Characteristics:
- Passes through all control points
- Very smooth appearance
- Popular for general smoothing
- Good for presentation graphics
Natural Spline
Creates smooth curves with natural boundary conditions:
data:
source: |
[
{"x": 0, "y": 20},
{"x": 1, "y": 35},
{"x": 2, "y": 25},
{"x": 3, "y": 45},
{"x": 4, "y": 30},
{"x": 5, "y": 50}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: natural
stroke: "#16a085"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 3
fill: "#16a085"Characteristics:
- Minimal curvature at endpoints
- Natural-looking curves
- Good for scientific data
- Reduces overshoot at boundaries
Monotone Curves
Monotone X
Preserves monotonicity in x-direction:
data:
source: |
[
{"x": 0, "y": 10},
{"x": 1, "y": 15},
{"x": 2, "y": 25},
{"x": 3, "y": 28},
{"x": 4, "y": 40},
{"x": 5, "y": 45}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: monotone-x
stroke: "#d35400"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 3
fill: "#d35400"Use Cases:
- Monotonically increasing/decreasing data
- Financial charts (prices always go up or down)
- Prevents artificial peaks and valleys
- Maintains data trends
Monotone Y
Preserves monotonicity in y-direction:
data:
source: |
[
{"x": 0, "y": 10},
{"x": 1, "y": 20},
{"x": 2, "y": 15},
{"x": 3, "y": 30},
{"x": 4, "y": 25},
{"x": 5, "y": 40}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: monotone-y
stroke: "#c0392b"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 3
fill: "#c0392b"Use Cases:
- Horizontal trends
- Time series with guaranteed monotonicity
- Growth/decay patterns
Bump Curves
Bump X
Creates smooth horizontal transitions:
data:
source: |
[
{"x": 0, "y": 20},
{"x": 1, "y": 40},
{"x": 2, "y": 30},
{"x": 3, "y": 50},
{"x": 4, "y": 35}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: bump-x
stroke: "#8e44ad"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 4
fill: "#8e44ad"Use Cases:
- Sankey-style diagrams
- Flow charts
- Ranking changes over time
- Horizontal emphasis
Bump Y
Creates smooth vertical transitions:
data:
source: |
[
{"x": 0, "y": 20},
{"x": 1, "y": 40},
{"x": 2, "y": 30},
{"x": 3, "y": 50},
{"x": 4, "y": 35}
]
width: 600
height: 350
marks:
- type: line
configuration:
x: x
y: y
curve: bump-y
stroke: "#2980b9"
strokeWidth: 2
- type: dot
configuration:
x: x
y: y
r: 4
fill: "#2980b9"Use Cases:
- Vertical flow diagrams
- Stream graphs
- Vertical ranking changes
Area Curves
Smooth Area Chart
Apply curves to area marks for smooth fills:
data:
source: |
[
{"date": "2024-01", "value": 100},
{"date": "2024-02", "value": 130},
{"date": "2024-03", "value": 115},
{"date": "2024-04", "value": 145},
{"date": "2024-05", "value": 160},
{"date": "2024-06", "value": 150}
]
width: 600
height: 350
marks:
- type: area
configuration:
x: date
y: value
curve: catmull-rom
fill: steelblue
fillOpacity: 0.4
- type: line
configuration:
x: date
y: value
curve: catmull-rom
stroke: steelblue
strokeWidth: 2Area Curve Tips:
- Match curve type between area and line marks
- Smooth curves create more organic appearance
- Good for highlighting trends
Curve Comparison
Side-by-Side Comparison
Compare multiple curve types:
data:
source: |
[
{"x": 0, "linear": 20, "basis": 20, "monotone": 20},
{"x": 1, "linear": 35, "basis": 35, "monotone": 35},
{"x": 2, "linear": 25, "basis": 25, "monotone": 25},
{"x": 3, "linear": 45, "basis": 45, "monotone": 45},
{"x": 4, "linear": 30, "basis": 30, "monotone": 30}
]
width: 600
height: 350
scales:
color:
legend: true
marks:
- type: line
configuration:
x: x
y: linear
curve: linear
stroke: red
strokeWidth: 2
- type: line
configuration:
x: x
y: basis
curve: basis
stroke: blue
strokeWidth: 2
- type: line
configuration:
x: x
y: monotone
curve: monotone-x
stroke: green
strokeWidth: 2Best Practices
Curve Selection Guide
Choose Linear When:
- Data has sharp transitions
- Precision is critical
- Interpolation would be misleading
- Performance is a concern
Choose Step When:
- Data represents discrete states
- Values are constant between observations
- Digital signals or categorical changes
Choose Smooth (Basis/Catmull-Rom) When:
- Aesthetic appearance matters
- Underlying process is continuous
- Minor overshooting is acceptable
- Presentation over precision
Choose Monotone When:
- Data must preserve increasing/decreasing trends
- Financial or scientific accuracy needed
- Artificial peaks/valleys would be misleading
Choose Bump When:
- Creating flow diagrams
- Sankey-style visualizations
- Emphasizing smooth transitions
- Ranking or hierarchy changes
Performance Considerations
Rendering Speed
Fastest to Slowest:
- Linear - Simple line segments
- Step - Horizontal/vertical segments only
- Monotone - Constrained cubic interpolation
- Basis - Cubic B-splines
- Cardinal/Catmull-Rom - Complex spline calculations
- Natural - Matrix operations for boundary conditions
Optimization Tips:
- Use linear for >1000 points
- Consider data sampling for smooth curves
- Test performance with your data size
Common Patterns
1. Smooth Time Series
marks:
- type: line
configuration:
x: date
y: value
curve: catmull-rom # Smooth, passes through points2. Step Function
marks:
- type: line
configuration:
x: time
y: state
curve: step-after # Constant until next value3. Monotonic Growth
marks:
- type: line
configuration:
x: date
y: cumulative
curve: monotone-x # Always increasing4. Natural Scientific Data
marks:
- type: line
configuration:
x: measurement
y: result
curve: natural # Minimal endpoint curvatureCurve Type Reference
| Curve Type | Passes Through Points | Smoothness | Best For |
|---|---|---|---|
linear | ✅ Yes | None | Default, precise data |
step | ✅ Yes | None | Discrete states |
step-after | ✅ Yes | None | State changes |
step-before | ✅ Yes | None | Leading indicators |
basis | ❌ No | Very High | Aesthetic smoothing |
cardinal | ✅ Yes | High | Smooth interpolation |
catmull-rom | ✅ Yes | High | General smoothing |
natural | ✅ Yes | High | Scientific data |
monotone-x | ✅ Yes | Medium | Monotonic trends |
monotone-y | ✅ Yes | Medium | Horizontal trends |
bump-x | ✅ Yes | Medium | Flow diagrams |
bump-y | ✅ Yes | Medium | Vertical flows |
Troubleshooting
Problem: Curve overshoots data points
- Solution: Use
monotone-xormonotone-yinstead - Alternative: Use
naturalfor minimal endpoint overshoot
Problem: Curve doesn't pass through points
- Solution: Avoid
basis- usecatmull-romorcardinal - Check: Verify curve spelling is correct
Problem: Jagged appearance with smooth curve
- Solution: Increase data density or simplify curve type
- Check: Ensure sufficient data points (minimum 3-4)
Problem: Performance issues
- Solution: Use
linearor reduce data points - Consider: Sampling data before visualization
Advanced Techniques
Custom Tension
Some curves support tension parameters (via Observable Plot options):
# Catmull-Rom with custom tension
marks:
- type: line
configuration:
x: x
y: y
curve: catmull-rom
tension: 0.5 # 0 = cardinal, 1 = tightMixed Curves
Use different curves for different series:
marks:
- type: line # Smooth primary trend
configuration:
x: date
y: actual
curve: catmull-rom
- type: line # Sharp forecast
configuration:
x: date
y: forecast
curve: linearRelated Examples
- Text Annotations - Label curve peaks and valleys
- Stacked Areas - Apply curves to stacked area charts
- Error Bars - Combine curves with confidence intervals
Last Updated: 2025-01-12Part of Phase 3: Advanced Mark Types