0
# Plotting and Visualization
1
2
Comprehensive visualization tools for portfolios, efficient frontiers, risk contributions, cluster analysis, and performance attribution. The plotting module provides publication-quality charts for portfolio analysis and presentation.
3
4
## Capabilities
5
6
### Efficient Frontier Plotting
7
8
Visualization of efficient frontiers and portfolio optimization results.
9
10
```python { .api }
11
def plot_frontier(w_frontier, mu, cov, returns, rm='MV', rf=0, alpha=0.05,
12
cmap='viridis', w=None, label='Portfolio', marker='*',
13
s=16, c='r', height=6, width=10, ax=None):
14
"""
15
Plot efficient frontier with risk-return profile.
16
17
Parameters:
18
- w_frontier (DataFrame): Efficient frontier weights matrix
19
- mu (DataFrame): Expected returns vector
20
- cov (DataFrame): Covariance matrix
21
- returns (DataFrame): Historical returns
22
- rm (str): Risk measure for frontier calculation
23
- rf (float): Risk-free rate
24
- alpha (float): Significance level for risk measures
25
- cmap (str): Colormap for frontier points
26
- w (DataFrame): Specific portfolio to highlight
27
- label (str): Label for highlighted portfolio
28
- marker (str): Marker style for highlighted portfolio
29
- s (float): Marker size for highlighted portfolio
30
- c (str): Color for highlighted portfolio
31
- height (float): Figure height
32
- width (float): Figure width
33
- ax (matplotlib.axes): Existing axes object
34
35
Returns:
36
matplotlib.axes: Axes object with frontier plot
37
"""
38
39
def plot_frontier_area(w_frontier, cov, returns, rm='MV', rf=0, alpha=0.05,
40
cmap='viridis', height=6, width=10, ax=None):
41
"""
42
Plot efficient frontier as filled area.
43
44
Parameters:
45
- w_frontier (DataFrame): Efficient frontier weights
46
- cov (DataFrame): Covariance matrix
47
- returns (DataFrame): Historical returns
48
- rm (str): Risk measure
49
- rf (float): Risk-free rate
50
- alpha (float): Significance level
51
- cmap (str): Colormap
52
- height (float): Figure height
53
- width (float): Figure width
54
- ax (matplotlib.axes): Existing axes
55
56
Returns:
57
matplotlib.axes: Axes object
58
"""
59
```
60
61
### Portfolio Composition
62
63
Visualization of portfolio allocations and weights.
64
65
```python { .api }
66
def plot_pie(w, title='Portfolio Composition', others=0.05, nrow=25,
67
cmap='tab20', height=6, width=8, ax=None):
68
"""
69
Plot portfolio allocation as pie chart.
70
71
Parameters:
72
- w (DataFrame): Portfolio weights
73
- title (str): Chart title
74
- others (float): Threshold for grouping small positions
75
- nrow (int): Maximum number of assets to show individually
76
- cmap (str): Colormap
77
- height (float): Figure height
78
- width (float): Figure width
79
- ax (matplotlib.axes): Existing axes
80
81
Returns:
82
matplotlib.axes: Axes object with pie chart
83
"""
84
85
def plot_bar(w, title='Portfolio Composition', kind='v', others=0.05,
86
nrow=25, cmap='tab20', height=6, width=10, ax=None):
87
"""
88
Plot portfolio allocation as bar chart.
89
90
Parameters:
91
- w (DataFrame): Portfolio weights
92
- title (str): Chart title
93
- kind (str): Bar orientation ('v' for vertical, 'h' for horizontal)
94
- others (float): Threshold for grouping small positions
95
- nrow (int): Maximum number of assets to show
96
- cmap (str): Colormap
97
- height (float): Figure height
98
- width (float): Figure width
99
- ax (matplotlib.axes): Existing axes
100
101
Returns:
102
matplotlib.axes: Axes object with bar chart
103
"""
104
```
105
106
### Risk Analysis Visualization
107
108
Charts for risk contribution analysis and risk decomposition.
109
110
```python { .api }
111
def plot_risk_con(w, cov, returns, rm='MV', rf=0, alpha=0.05, color='tab:blue',
112
height=6, width=10, ax=None):
113
"""
114
Plot risk contributions by asset.
115
116
Parameters:
117
- w (DataFrame): Portfolio weights
118
- cov (DataFrame): Covariance matrix
119
- returns (DataFrame): Historical returns
120
- rm (str): Risk measure
121
- rf (float): Risk-free rate
122
- alpha (float): Significance level
123
- color (str): Bar color
124
- height (float): Figure height
125
- width (float): Figure width
126
- ax (matplotlib.axes): Existing axes
127
128
Returns:
129
matplotlib.axes: Axes object with risk contribution chart
130
"""
131
132
def plot_factor_risk_con(w, cov, B, rm='MV', rf=0, alpha=0.05,
133
color='tab:blue', height=6, width=10, ax=None):
134
"""
135
Plot factor risk contributions.
136
137
Parameters:
138
- w (DataFrame): Portfolio weights
139
- cov (DataFrame): Factor covariance matrix
140
- B (DataFrame): Factor loadings
141
- rm (str): Risk measure
142
- rf (float): Risk-free rate
143
- alpha (float): Significance level
144
- color (str): Bar color
145
- height (float): Figure height
146
- width (float): Figure width
147
- ax (matplotlib.axes): Existing axes
148
149
Returns:
150
matplotlib.axes: Axes object with factor risk chart
151
"""
152
```
153
154
### Return Series Visualization
155
156
Time series plots and distribution analysis.
157
158
```python { .api }
159
def plot_series(returns, w=None, cmap='tab20', height=6, width=10, ax=None):
160
"""
161
Plot portfolio returns time series.
162
163
Parameters:
164
- returns (DataFrame): Returns data
165
- w (DataFrame): Portfolio weights (optional)
166
- cmap (str): Colormap for multiple series
167
- height (float): Figure height
168
- width (float): Figure width
169
- ax (matplotlib.axes): Existing axes
170
171
Returns:
172
matplotlib.axes: Axes object with time series plot
173
"""
174
175
def plot_hist(returns, w=None, alpha=0.05, bins=50, height=6, width=10, ax=None):
176
"""
177
Plot returns histogram with risk measures.
178
179
Parameters:
180
- returns (DataFrame): Returns data
181
- w (DataFrame): Portfolio weights for weighted returns
182
- alpha (float): Significance level for VaR/CVaR
183
- bins (int): Number of histogram bins
184
- height (float): Figure height
185
- width (float): Figure width
186
- ax (matplotlib.axes): Existing axes
187
188
Returns:
189
matplotlib.axes: Axes object with histogram
190
"""
191
192
def plot_drawdown(returns, w=None, alpha=0.05, height=6, width=10, ax=None):
193
"""
194
Plot drawdown time series.
195
196
Parameters:
197
- returns (DataFrame): Returns data
198
- w (DataFrame): Portfolio weights
199
- alpha (float): Significance level for drawdown measures
200
- height (float): Figure height
201
- width (float): Figure width
202
- ax (matplotlib.axes): Existing axes
203
204
Returns:
205
matplotlib.axes: Axes object with drawdown plot
206
"""
207
208
def plot_range(returns, w=None, alpha=0.05, height=6, width=10, ax=None):
209
"""
210
Plot returns range over time.
211
212
Parameters:
213
- returns (DataFrame): Returns data
214
- w (DataFrame): Portfolio weights
215
- alpha (float): Significance level
216
- height (float): Figure height
217
- width (float): Figure width
218
- ax (matplotlib.axes): Existing axes
219
220
Returns:
221
matplotlib.axes: Axes object with range plot
222
"""
223
```
224
225
### Clustering and Network Visualization
226
227
Visualization of asset relationships and clustering analysis.
228
229
```python { .api }
230
def plot_clusters(returns, codependence='pearson', linkage='ward', k=None,
231
max_k=10, leaf_order=True, cmap='viridis', height=8, width=10, ax=None):
232
"""
233
Plot clustered correlation matrix.
234
235
Parameters:
236
- returns (DataFrame): Returns data
237
- codependence (str): Codependence measure
238
- linkage (str): Linkage method for clustering
239
- k (int): Number of clusters (optional)
240
- max_k (int): Maximum clusters for optimization
241
- leaf_order (bool): Optimize leaf order
242
- cmap (str): Colormap for correlation matrix
243
- height (float): Figure height
244
- width (float): Figure width
245
- ax (matplotlib.axes): Existing axes
246
247
Returns:
248
matplotlib.axes: Axes object with clustered heatmap
249
"""
250
251
def plot_dendrogram(returns, codependence='pearson', linkage='ward',
252
k=None, max_k=10, leaf_order=True, height=6, width=10, ax=None):
253
"""
254
Plot hierarchical clustering dendrogram.
255
256
Parameters:
257
- returns (DataFrame): Returns data
258
- codependence (str): Codependence measure
259
- linkage (str): Linkage method
260
- k (int): Number of clusters to highlight
261
- max_k (int): Maximum clusters
262
- leaf_order (bool): Optimize leaf order
263
- height (float): Figure height
264
- width (float): Figure width
265
- ax (matplotlib.axes): Existing axes
266
267
Returns:
268
matplotlib.axes: Axes object with dendrogram
269
"""
270
271
def plot_network(returns, codependence='pearson', network='MST', k=None,
272
max_k=10, alpha_tail=0.05, gs_threshold=0.5, node_color='lightblue',
273
height=8, width=10, ax=None):
274
"""
275
Plot correlation network graph.
276
277
Parameters:
278
- returns (DataFrame): Returns data
279
- codependence (str): Codependence measure
280
- network (str): Network method ('MST', 'PMFG', 'TN', 'DBHT')
281
- k (int): Number of clusters
282
- max_k (int): Maximum clusters
283
- alpha_tail (float): Significance for tail dependence
284
- gs_threshold (float): Threshold for network connections
285
- node_color (str): Color for network nodes
286
- height (float): Figure height
287
- width (float): Figure width
288
- ax (matplotlib.axes): Existing axes
289
290
Returns:
291
matplotlib.axes: Axes object with network plot
292
"""
293
294
def plot_network_allocation(returns, w, codependence='pearson', network='MST',
295
cmap='viridis', height=8, width=10, ax=None):
296
"""
297
Plot network with portfolio allocation overlay.
298
299
Parameters:
300
- returns (DataFrame): Returns data
301
- w (DataFrame): Portfolio weights
302
- codependence (str): Codependence measure
303
- network (str): Network method
304
- cmap (str): Colormap for weight visualization
305
- height (float): Figure height
306
- width (float): Figure width
307
- ax (matplotlib.axes): Existing axes
308
309
Returns:
310
matplotlib.axes: Axes object with allocation network
311
"""
312
```
313
314
### Performance Attribution
315
316
Visualization of performance attribution analysis.
317
318
```python { .api }
319
def plot_BrinsonAttribution(Ra, Rb, Wa, Wb, height=6, width=10, ax=None):
320
"""
321
Plot Brinson performance attribution analysis.
322
323
Parameters:
324
- Ra (DataFrame): Portfolio returns
325
- Rb (DataFrame): Benchmark returns
326
- Wa (DataFrame): Portfolio weights
327
- Wb (DataFrame): Benchmark weights
328
- height (float): Figure height
329
- width (float): Figure width
330
- ax (matplotlib.axes): Existing axes
331
332
Returns:
333
matplotlib.axes: Axes object with attribution chart
334
"""
335
336
def plot_table(returns, w, MAR=0, alpha=0.05, height=9, width=12, ax=None):
337
"""
338
Plot portfolio statistics table.
339
340
Parameters:
341
- returns (DataFrame): Returns data
342
- w (DataFrame): Portfolio weights
343
- MAR (float): Minimum acceptable return
344
- alpha (float): Significance level
345
- height (float): Figure height
346
- width (float): Figure width
347
- ax (matplotlib.axes): Existing axes
348
349
Returns:
350
matplotlib.axes: Axes object with statistics table
351
"""
352
```
353
354
## Usage Examples
355
356
### Basic Portfolio Visualization
357
358
```python
359
import riskfolio as rp
360
import pandas as pd
361
import matplotlib.pyplot as plt
362
363
# Load data and create portfolio
364
returns = pd.read_csv('returns.csv', index_col=0, parse_dates=True)
365
port = rp.Portfolio(returns=returns)
366
port.assets_stats()
367
368
# Optimize portfolio
369
w = port.optimization(model='Classic', rm='MV', obj='Sharpe', rf=0.02)
370
371
# Plot portfolio composition
372
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))
373
374
rp.plot_pie(w, title='Portfolio Allocation', ax=ax1)
375
rp.plot_bar(w, title='Portfolio Weights', kind='v', ax=ax2)
376
377
plt.tight_layout()
378
plt.show()
379
380
# Plot risk contributions
381
fig, ax = plt.subplots(figsize=(12, 6))
382
rp.plot_risk_con(w, port.cov, returns, rm='MV', ax=ax)
383
plt.show()
384
```
385
386
### Efficient Frontier Analysis
387
388
```python
389
import riskfolio as rp
390
import pandas as pd
391
392
# Create portfolio and generate frontier
393
returns = pd.read_csv('returns.csv', index_col=0, parse_dates=True)
394
port = rp.Portfolio(returns=returns)
395
port.assets_stats()
396
397
# Generate efficient frontier
398
frontier = port.efficient_frontier(model='Classic', rm='MV', points=100)
399
400
# Plot frontier with specific portfolio highlighted
401
w_optimal = port.optimization(model='Classic', rm='MV', obj='Sharpe', rf=0.02)
402
403
ax = rp.plot_frontier(
404
w_frontier=frontier,
405
mu=port.mu,
406
cov=port.cov,
407
returns=returns,
408
rm='MV',
409
rf=0.02,
410
w=w_optimal,
411
label='Optimal Portfolio',
412
marker='*',
413
s=100,
414
c='red'
415
)
416
plt.show()
417
418
# Compare multiple risk measures
419
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
420
axes = axes.flatten()
421
422
risk_measures = ['MV', 'CVaR', 'MDD', 'CDaR']
423
for i, rm in enumerate(risk_measures):
424
frontier_rm = port.efficient_frontier(model='Classic', rm=rm, points=50)
425
rp.plot_frontier(
426
w_frontier=frontier_rm,
427
mu=port.mu,
428
cov=port.cov,
429
returns=returns,
430
rm=rm,
431
rf=0.02,
432
ax=axes[i]
433
)
434
axes[i].set_title(f'Efficient Frontier - {rm}')
435
436
plt.tight_layout()
437
plt.show()
438
```
439
440
### Clustering and Network Analysis
441
442
```python
443
import riskfolio as rp
444
import pandas as pd
445
import matplotlib.pyplot as plt
446
447
# Load returns
448
returns = pd.read_csv('returns.csv', index_col=0, parse_dates=True)
449
450
# Plot clustering analysis
451
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
452
453
# Dendrogram
454
rp.plot_dendrogram(
455
returns=returns,
456
codependence='pearson',
457
linkage='ward',
458
k=5,
459
ax=ax1
460
)
461
ax1.set_title('Hierarchical Clustering Dendrogram')
462
463
# Clustered correlation matrix
464
rp.plot_clusters(
465
returns=returns,
466
codependence='pearson',
467
linkage='ward',
468
k=5,
469
ax=ax2
470
)
471
ax2.set_title('Clustered Correlation Matrix')
472
473
# Network plot
474
rp.plot_network(
475
returns=returns,
476
codependence='pearson',
477
network='MST',
478
k=5,
479
ax=ax3
480
)
481
ax3.set_title('Minimum Spanning Tree Network')
482
483
# Portfolio allocation on network
484
port = rp.Portfolio(returns=returns)
485
port.assets_stats()
486
w = port.optimization(obj='Sharpe', rm='MV', rf=0.02)
487
488
rp.plot_network_allocation(
489
returns=returns,
490
w=w,
491
codependence='pearson',
492
network='MST',
493
ax=ax4
494
)
495
ax4.set_title('Portfolio Allocation Network')
496
497
plt.tight_layout()
498
plt.show()
499
```
500
501
### Time Series and Distribution Analysis
502
503
```python
504
import riskfolio as rp
505
import pandas as pd
506
import matplotlib.pyplot as plt
507
508
# Load returns
509
returns = pd.read_csv('returns.csv', index_col=0, parse_dates=True)
510
511
# Create equal-weight and optimized portfolios
512
port = rp.Portfolio(returns=returns)
513
port.assets_stats()
514
515
w_equal = pd.DataFrame(1/len(returns.columns), index=returns.columns, columns=['weights'])
516
w_optimal = port.optimization(obj='Sharpe', rm='MV', rf=0.02)
517
518
# Calculate portfolio returns
519
ret_equal = (returns * w_equal.T).sum(axis=1)
520
ret_optimal = (returns * w_optimal.T).sum(axis=1)
521
522
# Plot comparisons
523
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
524
525
# Time series
526
combined_returns = pd.DataFrame({
527
'Equal Weight': ret_equal,
528
'Optimized': ret_optimal
529
})
530
rp.plot_series(combined_returns, ax=ax1)
531
ax1.set_title('Portfolio Returns Comparison')
532
533
# Histograms
534
rp.plot_hist(combined_returns, alpha=0.05, ax=ax2)
535
ax2.set_title('Returns Distribution')
536
537
# Drawdowns
538
rp.plot_drawdown(combined_returns, alpha=0.05, ax=ax3)
539
ax3.set_title('Drawdown Analysis')
540
541
# Rolling performance
542
rp.plot_range(combined_returns, alpha=0.05, ax=ax4)
543
ax4.set_title('Rolling Performance Range')
544
545
plt.tight_layout()
546
plt.show()
547
```
548
549
## Visualization Parameters
550
551
### Common Parameters
552
553
- **height, width**: Figure dimensions
554
- **ax**: Matplotlib axes object for subplot integration
555
- **cmap**: Colormap for data visualization
556
- **alpha**: Significance level for risk measures
557
- **color**: Color specification for single-color plots
558
559
### Network Methods
560
561
- **MST**: Minimum Spanning Tree
562
- **PMFG**: Planar Maximally Filtered Graph
563
- **TN**: Threshold Network
564
- **DBHT**: Direct Bubble Hierarchical Tree
565
566
### Codependence Measures
567
568
- **pearson**: Pearson correlation
569
- **spearman**: Spearman rank correlation
570
- **abs_pearson**: Absolute Pearson correlation
571
- **distance_corr**: Distance correlation
572
- **mutual_info**: Mutual information
573
- **tail**: Lower tail dependence