<think>我们有两个数据集:一个是按年龄分组的平均年代数据,另一个是每个年龄组的人数。需求:1.以年龄组(如20-29,30-39等)为X轴。2.绘制三条折线图,分别代表三列年代数据(2015.833,2017.6667等),且每个数据点的样式不同(比如不同形状)。3.同时绘制一个柱状图,表示每个年龄组的人数(15,113,235,412,365,279,58)。由于数值范围差异大,使用双Y轴,即左侧Y轴为年代(折线图),右侧Y轴为数量(柱状图)。4.图例需要清晰标注。步骤:-我们将使用matplotlib库来实现。-首先,我们需要准备数据。给定的数据分为两个部分:第一块(折线图数据):年龄组:['20-29','30-39','40-49','50-59','60-69','70-79','80-91']数据1:[2015.833,2011.617,2007.228,2004.273,1997.333,1984.883,1975.692]数据2:[2017.6667,2014.5,2012.364,2009.358,2003.454,1994.932,1989.833]数据3:[2014.8,2013.556,2007.549,2004.273,1996.104,1984.154,1977.857]数据4(单独一列年代,似乎是另一条折线):[2015,2010,2003,1997,1992,1987,1970]注意:题目中提到了“各个折线图点的样式不同”,我们将会为每条折线设置不同的标记(marker)。第二块(柱状图数据):数量:[15,113,235,412,365,279,58]-我们将年龄组作为X轴的标签。注意,这里有7个年龄组。-由于柱状图的数据范围(最大412)与折线图的数据范围(约1970-2018)差异很大,因此采用双Y轴。-具体步骤:1.创建图形和第一个坐标轴(用于折线图)。2.在第一个坐标轴上绘制4条折线(因为有4列年代数据)。3.创建第二个坐标轴,共享相同的X轴,但Y轴在右侧,用于柱状图。4.在第二个坐标轴上绘制柱状图。5.设置图例,分别说明折线和柱状图。代码实现:我们将使用plt.subplots创建图形和第一个坐标轴,然后用twinx()创建第二个坐标轴。注意:由于题目要求四条折线(但原始数据给了四个年代列),所以我们将绘制四条折线。但是,观察数据,原始数据中第四列年代数据是单独一列,并没有与其他三列在同一行上对齐?不过根据题目给出的格式,实际上是每行对应一个年龄组,因此四个年代列都是7个数据点。让我们明确一下数据:年龄组=['20-29','30-39','40-49','50-59','60-69','70-79','80-91']line1=[2015.833,2011.617,2007.228,2004.273,1997.333,1984.883,1975.692]line2=[2017.6667,2014.5,2012.364,2009.358,2003.454,1994.932,1989.833]line3=[2014.8,2013.556,2007.549,2004.273,1996.104,1984.154,1977.857]line4=[2015,2010,2003,1997,1992,1987,1970](注意:这里最后一个1970,而line1最后一个1975.692,所以是四个不同的数据序列)柱状图数据:bar_data=[15,113,235,412,365,279,58]我们将用四个不同的折线标记来区分它们。标记可选:['o','s','^','D']等(圆形,方形,三角形,菱形)此外,为了在双Y轴情况下正确显示图例,我们需要分别收集折线的图例句柄和柱状图的图例句柄。代码:</think>
以下是一个完整的 Python 实现方案,使用 Matplotlib 创建双Y轴图表(折线图 + 柱状图),并处理你提供的数据:
```python
import matplotlib.pyplot as plt
import numpy as np
# 设置全局字体和图表尺寸
plt.rcParams.update({'font.size': 10})
plt.figure(figsize=(12, 8))
# 输入数据
age_groups = ['20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80-91']
line1 = [2015.833, 2011.617, 2007.228, 2004.273, 1997.333, 1984.883, 1975.692]
line2 = [2017.6667, 2014.5, 2012.364, 2009.358, 2003.454, 1994.932, 1989.833]
line3 = [2014.8, 2013.556, 2007.549, 2004.273, 1996.104, 1984.154, 1977.857]
line4 = [2015, 2010, 2003, 1997, 1992, 1987, 1970]
bar_data = [15, 113, 235, 412, 365, 279, 58]
x = np.arange(len(age_groups)) # X轴位置
# 创建主坐标轴(用于折线)
ax1 = plt.gca()
# 绘制四条折线(不同样式和颜色)
line1_plot, = ax1.plot(x, line1, 'o-', color='#1f77b4', markersize=8, linewidth=2, label='数据集1')
line2_plot, = ax1.plot(x, line2, 's--', color='#ff7f0e', markersize=8, linewidth=2, label='数据集2')
line3_plot, = ax1.plot(x, line3, 'D-.', color='#2ca02c', markersize=8, linewidth=2, label='数据集3')
line4_plot, = ax1.plot(x, line4, 'v:', color='#d62728', markersize=8, linewidth=2, label='数据集4')
# 创建次坐标轴(用于柱状图)
ax2 = ax1.twinx()
bar_plot = ax2.bar(x, bar_data, width=0.6, alpha=0.7, color='#8c564b', label='数量分布')
# 设置坐标轴标签
ax1.set_xlabel('年龄分组', fontsize=12)
ax1.set_ylabel('年份', fontsize=12)
ax2.set_ylabel('样本数量', fontsize=12)
# 设置刻度位置和标签
ax1.set_xticks(x)
ax1.set_xticklabels(age_groups, rotation=45)
ax1.set_ylim(1960, 2030) # 折线图Y轴范围
# 添加水平网格线
ax1.grid(axis='y', linestyle='--', alpha=0.7)
# 添加柱状图标签
for i, v in enumerate(bar_data):
ax2.text(i, v + 10, str(v), ha='center', va='bottom')
# 合并图例
lines = [line1_plot, line2_plot, line3_plot, line4_plot, bar_plot]
labels = [l.get_label() for l in lines]
ax1.legend(lines, labels, loc='upper left', frameon=True)
# 添加标题
plt.title('不同年龄段的时间序列与数量分布', pad=20, fontsize=14)
# 调整布局
plt.tight_layout()
plt.show()
```
### 代码解释:
1. **数据准备**:
- `age_groups`: X轴标签(年龄分组)
- 4个折线数据集 (`line1`, `line2`, `line3`, `line4`)
- `bar_data`: 柱状图数据(样本数量)
2. **双Y轴设置**:
- 主坐标轴 `ax1` 用于折线图(年份)
- 次坐标轴 `ax2` 用于柱状图(数量),使用 `twinx()` 创建
3. **折线图样式**:
- 四条线分别使用不同标记(圆形、方形、菱形、倒三角)
- 不同线型(实线、虚线、点划线、点线)
- 使用不同颜色增强区分度
4. **柱状图设置**:
- 半透明棕色柱体避免视觉冲突
- 在每个柱体顶部添加数值标签
5. **坐标轴调整**:
- 旋转X轴标签避免重叠
- 设置折线Y轴范围(1960-2030)
- 添加网格线提高可读性
6. **图例处理**:
- 合并两个坐标轴的图例统一显示
- 包含所有数据系列标签
### 效果说明:
- 左侧Y轴:显示年份(折线图)
- 右侧Y轴:显示数量(柱状图)
- 四条折线分别表示四个时间序列数据集
- 柱状图显示各年龄段的样本数量分布
- 自动计算最佳间距确保图表清晰可读