Skip to content

Commit 4ec2e0b

Browse files
Added show_values
1 parent d7f2fc6 commit 4ec2e0b

2 files changed

Lines changed: 33 additions & 3 deletions

File tree

pypfopt/plotting.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ def _plot_io(**kwargs):
6666
plt.show()
6767

6868

69-
def plot_covariance(cov_matrix, plot_correlation=False, show_tickers=True, **kwargs):
69+
def plot_covariance(
70+
cov_matrix, plot_correlation=False, show_tickers=True, show_values=False, **kwargs
71+
):
7072
"""
7173
Generate a basic plot of the covariance (or correlation) matrix, given a
7274
covariance matrix.
@@ -80,6 +82,9 @@ def plot_covariance(cov_matrix, plot_correlation=False, show_tickers=True, **kwa
8082
show_tickers : bool, optional
8183
whether to use tickers as labels (not recommended for large portfolios),
8284
defaults to True
85+
show_values : bool, optional
86+
if True, annotate each cell with the numeric value formatted to
87+
two decimal places. Defaults to False.
8388
8489
Returns
8590
-------
@@ -92,6 +97,7 @@ def plot_covariance(cov_matrix, plot_correlation=False, show_tickers=True, **kwa
9297
matrix = risk_models.cov_to_corr(cov_matrix)
9398
else:
9499
matrix = cov_matrix
100+
95101
fig, ax = plt.subplots()
96102

97103
cax = ax.imshow(matrix)
@@ -104,6 +110,30 @@ def plot_covariance(cov_matrix, plot_correlation=False, show_tickers=True, **kwa
104110
ax.set_yticklabels(matrix.index)
105111
plt.xticks(rotation=90)
106112

113+
# Optional: overlay numeric values on each cell
114+
if show_values:
115+
is_dataframe = hasattr(matrix, "iloc")
116+
n_rows, n_cols = matrix.shape
117+
118+
for i in range(n_rows):
119+
for j in range(n_cols):
120+
if is_dataframe:
121+
val = matrix.iloc[i, j]
122+
else:
123+
val = matrix[i, j]
124+
125+
text_str = f"{val:.2f}"
126+
127+
ax.text(
128+
j,
129+
i,
130+
text_str,
131+
ha="center",
132+
va="center",
133+
color="w",
134+
fontsize=plt.rcParams.get("font.size", 10) * 0.9,
135+
)
136+
107137
_plot_io(**kwargs)
108138

109139
return ax

tests/test_efficient_frontier.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ def test_min_vol_pair_constraint():
608608
ef.min_volatility()
609609
old_sum = ef.weights[:2].sum()
610610
ef = setup_efficient_frontier()
611-
ef.add_constraint(lambda w: (w[1] + w[0] <= old_sum / 2))
611+
ef.add_constraint(lambda w: w[1] + w[0] <= old_sum / 2)
612612
ef.min_volatility()
613613
new_sum = ef.weights[:2].sum()
614614
assert new_sum <= old_sum / 2 + 1e-4
@@ -620,7 +620,7 @@ def test_max_sharpe_pair_constraint():
620620
old_sum = ef.weights[:2].sum()
621621

622622
ef = setup_efficient_frontier()
623-
ef.add_constraint(lambda w: (w[1] + w[0] <= old_sum / 2))
623+
ef.add_constraint(lambda w: w[1] + w[0] <= old_sum / 2)
624624
ef.max_sharpe(risk_free_rate=0.02)
625625
new_sum = ef.weights[:2].sum()
626626
assert new_sum <= old_sum / 2 + 1e-4

0 commit comments

Comments
 (0)