表格样式
只有横线的表格(无垂直线),顶线、底线和标题行加粗,其余横线淡化。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
# 设置seaborn风格以获得更美观的图表
sns.set_style("white")
# 示例数据
data = {
'Variable': ['A', 'B', 'C', 'D'],
'Mean': [10.5, 20.3, 15.7, 12.8],
'Std Dev': [1.2, 2.5, 1.8, 1.4],
'N': [100, 150, 120, 130]
}
df = pd.DataFrame(data)
# 创建PDF
with PdfPages('output.pdf') as pdf:
# 第一页:示例图像
plt.figure(figsize=(8.5, 11)) # 标准A4尺寸(英寸)
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.title('Sample Plot', fontsize=14, pad=10)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend()
plt.tight_layout()
pdf.savefig()
plt.close()
# 第二页:三线式表格
fig, ax = plt.subplots(figsize=(8.5, 11))
ax.axis('off') # 隐藏坐标轴
# 创建表格
table = ax.table(cellText=df.values,
colLabels=df.columns,
loc='center',
cellLoc='center',
colColours=['white'] * len(df.columns))
# 设置表格样式
table.auto_set_font_size(False)
table.set_fontsize(10)
table.scale(1.2, 1.2) # 调整表格大小
# 三线式表格样式
for (i, j), cell in table.get_celld().items():
cell.set_text_props(ha='center', va='center')
cell.set_edgecolor('black')
if i == 0: # 标题行
cell.set_text_props(weight='bold')
cell.set_facecolor('white')
cell.set_height(0.05)
cell.set_linewidth(2)
cell.visible_edges = 'horizontal' # 上下边框
elif i == len(df): # 底线
cell.set_linewidth(2)
cell.visible_edges = 'B' # 仅显示下边框
else: # 中间横线
cell.set_linewidth(0.5)
cell.visible_edges = 'B' # 仅显示下边框
pdf.savefig()
plt.close()
- 目标样式:
- 只有横线,无垂直线。
- 顶线(表格最上方)、标题线下方线和底线加粗。
- 标题行文字加粗。
- 其他中间横线淡化。
案例分析
- 尝试融合其他图表:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
from matplotlib.backends.backend_pdf import PdfPages
import seaborn as sns
# Set Seaborn style for better aesthetics
sns.set_style("darkgrid")
sns.set_palette("husl")
# Monte Carlo simulation parameters
np.random.seed(42)
n_simulations = 5
years = np.arange(2001, 2101)
n_years = len(years)
initial_value = 1000 # Starting net value in 2001
annual_return = 0.05 # Expected annual return
volatility = 0.1 # Annual volatility
fixed_value_2100 = initial_value * (1 + annual_return) ** n_years # Deterministic value in 2100
# Simulate net value paths using geometric Brownian motion
dt = 1 # Time step (1 year)
paths = np.zeros((n_simulations, n_years))
paths[:, 0] = initial_value
for t in range(1, n_years):
random_shocks = np.random.normal(0, 1, n_simulations)
paths[:, t] = paths[:, t-1] * np.exp((annual_return - 0.5 * volatility**2) * dt + volatility * np.sqrt(dt) * random_shocks)
# Create DataFrame for paths
paths_df = pd.DataFrame(paths, index=[f"Sim_{i+1}" for i in range(n_simulations)], columns=years)
base_path = initial_value * (1 + annual_return) ** np.arange(n_years)
base_df = pd.DataFrame([base_path], index=["Base"], columns=years)
# Extract 2100 net values
net_values_2100 = paths_df[2100]
base_net_value_2100 = base_df[2100].iloc[0]
ratios_2100 = (net_values_2100 / fixed_value_2100) - 1
# Statistical table data
stats_data = {
'Simulation': [f"Sim_{i+1}" for i in range(n_simulations)],
'Net Value (2100)': net_values_2100.values,
'Ratio (2100)': ratios_2100.values
}
stats_df = pd.DataFrame(stats_data)
# Create PDF
with PdfPages('monte_carlo_output.pdf') as pdf:
# First page: Three subfigures
fig = plt.figure(figsize=(12, 8)) # A4 size in inches
gs = GridSpec(1, 3, width_ratios=[6, 1, 1]) # Left plot wider
# Left: Monte Carlo paths
ax1 = fig.add_subplot(gs[0])
colors = sns.color_palette("husl", n_simulations)
for idx, color in zip(paths_df.index, colors):
ax1.plot(years, paths_df.loc[idx], color=color, label=idx, linewidth=1.5)
ax1.plot(years, base_df.loc["Base"], color='black', linestyle='--', label='Base', linewidth=1.5)
ax1.set_title("Monte Carlo Net Value Paths (2001-2100)", fontsize=12)
ax1.set_xlabel("Year", fontsize=10)
ax1.set_ylabel("Net Value", fontsize=10)
ax1.legend(loc='upper left', fontsize=8)
ax1.grid(True)
# Middle: Net value number line (2100)
ax2 = fig.add_subplot(gs[1])
ax2.axhline(base_net_value_2100, color='black', linestyle='--', alpha=0.3, label='Base')
for idx, color, value in zip(net_values_2100.index, colors, net_values_2100):
ax2.scatter(0, value, color=color, s=100, label=idx)
ax2.annotate(f'{value:.2f}', (0.05, value), fontsize=8, color=color)
ax2.set_xlim(-0.5, 0.5)
ax2.set_ylim(net_values_2100.min() * 0.9, net_values_2100.max() * 1.1)
ax2.set_xticks([])
ax2.set_title("Net Value (2100)", fontsize=12)
ax2.set_ylabel("Net Value", fontsize=10)
ax2.grid(True, axis='y')
# Right: Ratio number line (2100)
ax3 = fig.add_subplot(gs[2])
ax3.axhline(0, color='black', linestyle='--', alpha=0.3, label='Zero')
for idx, color, ratio in zip(ratios_2100.index, colors, ratios_2100):
ax3.scatter(0, ratio, color=color, s=100, label=idx)
ax3.annotate(f'{ratio:.2%}', (0.05, ratio), fontsize=8, color=color)
ax3.set_xlim(-0.5, 0.5)
ax3.set_ylim(ratios_2100.min() * 0.9, ratios_2100.max() + 0.1 * 1.1)
ax3.set_xticks([])
ax3.set_title("Ratio (Sim/Fixed - 1, 2100)", fontsize=12)
ax3.set_ylabel("Ratio", fontsize=10)
ax3.grid(True, axis='y')
plt.tight_layout()
pdf.savefig(dpi=300)
plt.close()
# Second page: Three-line statistical table
fig, ax = plt.subplots(figsize=(8.5, 11))
ax.axis('off') # Hide axes
# Create table
table = ax.table(cellText=stats_df.values,
colLabels=stats_df.columns,
loc='center',
cellLoc='center',
colColours=['white'] * len(stats_df.columns))
# Set table styles
table.auto_set_font_size(False)
table.set_fontsize(10)
table.scale(1.2, 1.2)
# Three-line table style
for (i, j), cell in table.get_celld().items():
cell.set_text_props(ha='center', va='center')
cell.set_edgecolor('black')
if i == 0: # Header row
cell.set_text_props(weight='bold')
cell.set_facecolor('white')
cell.set_height(0.05)
cell.set_linewidth(2)
cell.visible_edges = 'horizontal'
elif i == len(stats_df): # Bottom line
cell.set_linewidth(2)
cell.visible_edges = 'B'
else: # Middle rows
cell.set_linewidth(0.5)
cell.visible_edges = 'B'
pdf.savefig(dpi=300)
plt.close()
print("Output saved as 'monte_carlo_output.pdf'.")
880

被折叠的 条评论
为什么被折叠?



