<think>我们要求一行放两个图,因此每个图的宽度应该小于等于A4纸宽度的一半(考虑到边距)。A4纸的宽度通常为210mm,即21cm。我们通常设置两个图并排,每个图宽度大约8cm(80mm),高度6cm(60mm)是常见的。因此,我们将每个图的尺寸设置为3.15英寸(8cm)宽,2.36英寸(6cm)高(因为1英寸=2.54cm,所以8cm≈3.15英寸,6cm≈2.36英寸)。
但是,我们还需要调整字体大小,以确保在缩小图形后文字仍然清晰可读。我们已经定义了一个字体大小字典PAPER_FONT_SIZES,用于控制标题、标签、刻度、图例和注释的字体大小。
此外,我们还需要调整标记点的大小和线宽,使得图形在缩小后不会显得过于拥挤。
目前代码中已经设置了图形尺寸为(3.15, 2.36),这是正确的。但是,我们还需要检查以下方面:
1. 坐标轴标签、标题、刻度标签的字体大小是否足够小以适应小图,同时又要保证在论文中清晰可读。
我们设置:标题9pt,坐标轴标签8pt,刻度7pt,图例7pt,注释6pt。这些设置在A4纸一行两个图的情况下通常是合适的。
2. 图例的位置和大小:图例使用7pt字体,并且放在最佳位置(loc='best'),避免遮挡数据。
3. 缺失值标记:我们将其标记在数据最小值下方7%的位置,并添加时间标签(使用6pt字体)。
4. 横坐标时间标签的旋转角度为30度,并且水平对齐方式为居中(ha='center'),以避免重叠。
5. 使用tight_layout(pad=0.5)来减少图形周围的空白。
6. 保存为PDF格式,这样在论文中插入时不会失真。
根据以上设置,代码已经基本满足要求。但是,为了确保一行两个图的效果,我们还需要在最终排版时注意:
在LaTeX中,可以使用例如`\includegraphics[width=0.45\textwidth]{figure.pdf}`来并排放置两个图形。
然而,如果发现生成的图形在并排时字体仍然偏大或偏小,我们可以进一步调整PAPER_FONT_SIZES字典中的数值。
另外,我们还需要注意:在生成图形时,每个图形只包含一个变量。因此,我们需要对每个变量分别调用函数。
现在,代码中已经循环处理每个变量(除了时间列和单位映射表中存在的列)。我们只需要确保单位映射表`units`包含了所有需要绘制的列。
如果发现图形中的线、点、文字等元素在小图上显得过大,我们可以进一步减小线宽(linewidth)、标记大小(markersize)和注释的偏移量(xytext)等。
当前设置:
- 线宽:1.2
- 标记大小:3
- 缺失值标记大小:25(散点的大小,即s=25),这个大小是点的大小,在6cm高的图上可能偏大,可以调整为15。
- 缺失值标记的线宽:0.8
我们可以尝试将缺失值标记的大小调整为15,并确保缺失值的时间标签字体为6pt(即PAPER_FONT_SIZES['annotation']=6)。
修改缺失值标记的部分:
原代码:s=25 -> 改为s=15
另外,缺失值标记的位置(y_marker)是在最小值下方7%的位置,如果图形高度缩小,这个位置可能需要调整。但考虑到图形高度已经固定,且我们调整了标记大小,暂时先调整大小。
此外,我们还可以考虑将图例放在图形内部(例如右上角)以避免增加图形的高度。但代码中已经使用loc='best',由matplotlib自动选择最佳位置。
如果图例遮挡了数据,我们可以手动调整图例位置。但为了自动化,我们暂时使用最佳位置。
修改后的缺失值标记代码:
scatter = ax.scatter(missing_times,
[y_marker] * len(missing_times),
color='red', s=15, zorder=5, # 修改s=15
marker='x', linewidths=0.8)
我们将在函数中进行此修改。
另外,由于图形较小,横坐标的刻度标签可能会重叠。我们之前已经将旋转角度设置为30度,并水平对齐为居中(ha='center'),这有助于减少重叠。如果数据点很多(比如超过24个月),可以考虑只显示年份或隔几个月显示一个标签。但为了通用性,我们先按当前方法处理。
如果时间跨度很长,我们可以使用`MaxNLocator`来控制显示的刻度数量,例如最多显示6个刻度。但考虑到我们数据量不大(从2020年开始,假设有24个月),所以暂时不调整。
如果数据点很多,我们可以使用`plt.xticks`来手动设置刻度位置和标签。
考虑到通用性,我们暂时不添加这个功能,因为我们的数据点不会太多(月度数据,最多几十个点)。
现在,我们修改函数中的缺失值标记大小,并将图形保存为PDF。
修改后的函数如下:
</think>
我理解您需要修改代码以生成一行能放两个图的尺寸,同时保持字体清晰可见。以下是优化后的代码,主要调整了图表尺寸、字体大小和布局:
```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from pathlib import Path
import numpy as np
from matplotlib.ticker import MaxNLocator
import matplotlib as mpl
from datetime import datetime
# 1. 数据准备
file_path = r"D:\研究生\竞赛\能源经济学术创意大赛\yuce.xlsx"
df = pd.read_excel(file_path)
# 创建输出目录
output_dir = Path(r"D:\研究生\竞赛\能源经济学术创意大赛") / "论文图表"
output_dir.mkdir(parents=True, exist_ok=True)
# 2. 设置兼容中文字体的配置
plt.rcParams['font.family'] = ['SimHei'] # 使用黑体,更清晰
plt.rcParams['axes.unicode_minus'] = False # 正确显示负号
# 3. 论文图表全局参数设置 - 优化为一行两图尺寸
plt.rcParams['figure.dpi'] = 300 # 高分辨率
plt.rcParams['savefig.format'] = 'pdf' # PDF格式适合论文
plt.rcParams['savefig.bbox'] = 'tight'
plt.rcParams['savefig.pad_inches'] = 0.05 # 减少边距
# 优化字体大小设置 - 适合小尺寸图表
PAPER_FONT_SIZES = {
'title': 10, # 标题稍大保证可读
'label': 9, # 轴标签
'tick': 8, # 刻度标签
'legend': 8, # 图例
'annotation': 7 # 注释
}
# 4. 单位映射表
units = {
"政策强度": "无量纲",
"太阳能发电量(万千瓦时)": "万千瓦时",
"风力发电量(亿千瓦时)": "亿千瓦时",
"水平面太阳总辐射量(千瓦时/平方米)": "kWh/m²",
"平均风速(m/s)": "m/s",
"工业增加值同比增长(%)": "%"
}
# 5. 创建适合论文的折线图 (优化为一页两图尺寸)
def create_paper_line_plot(data, time_column, var_name, unit):
"""创建适合论文排版的小尺寸折线图"""
# 设置图表尺寸:一行两图的尺寸 (8cm x 6cm)
fig, ax = plt.subplots(figsize=(8/2.54, 6/2.54)) # 转换为英寸(1英寸=2.54cm)
# 确保时间列是datetime类型
if not pd.api.types.is_datetime64_any_dtype(data[time_column]):
data[time_column] = pd.to_datetime(data[time_column])
# 使用时间序列作为横坐标
x_values = data[time_column]
# 绘制主折线 - 优化为更细的线宽
line, = ax.plot(x_values, data[var_name],
color='#1f77b4', linewidth=1.0, # 线宽减小
marker='o', markersize=2.5, # 标记减小
label=var_name, zorder=3)
# 识别缺失值
missing_mask = data[var_name].isnull()
missing_indices = np.where(missing_mask)[0]
# 标记缺失值(显示时间索引)
if len(missing_indices) > 0:
# 获取缺失值对应的时间点
missing_times = x_values[missing_indices]
# 计算标记点的y位置
y_min = data[var_name].min()
y_max = data[var_name].max()
y_range = y_max - y_min
y_marker = y_min - 0.05 * y_range # 更接近数据线
# 绘制缺失值标记
scatter = ax.scatter(missing_times,
[y_marker] * len(missing_times),
color='red', s=15, zorder=5, # 减小标记大小
marker='x', linewidths=0.7)
# 添加数据标签(显示时间索引)
for t in missing_times:
# 格式化时间显示
if pd.api.types.is_datetime64_any_dtype(type(t)):
time_str = t.strftime('%Y-%m')
else:
time_str = str(t)
ax.annotate(time_str,
(t, y_marker),
textcoords="offset points",
xytext=(0, -6), # 减小偏移量
ha='center',
fontsize=PAPER_FONT_SIZES['annotation'],
color='red',
alpha=0.8)
# 优化横坐标显示
fig.autofmt_xdate(rotation=30, ha='right') # 调整旋转角度和对齐方式
# 添加标题和标签(适合小尺寸图表)
ax.set_title(f"{var_name} ({unit})",
fontsize=PAPER_FONT_SIZES['title'],
pad=4) # 减小内边距
ax.set_xlabel('时间',
fontsize=PAPER_FONT_SIZES['label'],
labelpad=2)
ax.set_ylabel(unit,
fontsize=PAPER_FONT_SIZES['label'],
labelpad=2)
# 网格线更细更淡
ax.grid(True, linestyle=':', alpha=0.2, linewidth=0.3) # 虚线更细
# 添加图例(更小尺寸)
legend = ax.legend(loc='best',
frameon=True,
fontsize=PAPER_FONT_SIZES['legend'],
framealpha=0.7)
legend.get_frame().set_linewidth(0.5) # 图例边框更细
# 设置刻度字体大小
ax.tick_params(axis='both',
which='major',
labelsize=PAPER_FONT_SIZES['tick'],
length=3, width=0.5) # 刻度线更短更细
# 优化布局
plt.tight_layout(pad=0.8) # 减小内边距
# 保存为PDF格式
safe_var_name = var_name.replace('/', '_').replace('(', '').replace(')', '')
save_path = output_dir / f"{safe_var_name}.pdf"
plt.savefig(save_path, format='pdf', bbox_inches='tight')
plt.close()
print(f"已保存论文图表: {save_path}")
return save_path
# 6. 为每个变量生成论文图表
time_column = "时间" # 请替换为实际的时间列名称
# 检查时间列是否存在
if time_column not in df.columns:
print(f"警告: 数据框中不存在 '{time_column}' 列,将使用行索引作为时间序列")
start_date = datetime(2020, 1, 1)
df[time_column] = [start_date + pd.DateOffset(months=i) for i in range(len(df))]
for col in df.columns:
if col in units and col != time_column:
print(f"正在生成论文版 {col} 图表...")
pdf_path = create_paper_line_plot(df, time_column, col, units[col])
print(f"\n所有论文图表已保存到: {output_dir}")
print("图表尺寸已优化为一行两图(8cm×6cm),字体清晰可见")
```
### 主要优化点:
1. **尺寸优化**:
- 图表尺寸设置为 `(8/2.54, 6/2.54)` 英寸 ≈ 8cm×6cm
- 一行可以完美放置两个图表(A4纸宽度21cm,两边各留2.5cm边距)
2. **字体优化**:
- 使用黑体(SimHei)保证中文字符清晰
- 调整字体层级:
- 标题:10pt
- 轴标签:9pt
- 刻度:8pt
- 图例:8pt
- 注释:7pt
3. **元素精细化**:
- 线宽从1.2减小到1.0
- 标记大小从3减小到2.5
- 缺失值标记大小从25减小到15
- 刻度线更短更细
- 图例边框更细
4. **布局优化**:
- 减小所有内边距(pad)参数
- 网格线改为虚线(:)并降低透明度
- X轴标签旋转角度调整为30度,右对齐(ha='right')
- 缺失值标记位置更接近数据线(y_marker)
5. **输出优化**:
- 边距减少到0.05英寸
- 使用tight_layout(pad=0.8)压缩空白区域
这些优化确保在8cm×6cm的小尺寸图表上,所有文字元素仍然清晰可读,同时一行可以放置两个图表,适合学术论文排版要求。