
代码绘制成果展示








代码解释


第一部分

# =========================================================================================# ====================================== 1. 库的导入 =========================================# =========================================================================================import matplotlib.pyplot as pltimport numpy as npimport pandas as pdimport matplotlib.gridspec as gridspecfrom matplotlib.patches import Rectangleimport matplotlibplt.rcParams['font.family'] = 'serif'plt.rcParams['font.serif'] = ['Times New Roman']matplotlib.rcParams['pdf.fonttype'] = 42matplotlib.rcParams['ps.fonttype'] = 42

第二部分

# =========================================================================================# ====================================== 2.颜色库=========================================# =========================================================================================COLOR_SCHEMES = {1: ['#7b97c3', '#e8a97d', '#f7e193', '#e9a7b9', '#92b995'],}

第三部分

# =========================================================================================# ======================================3.内嵌的3D饼图绘制函数=========================================# =========================================================================================def draw_3d_pie(parent_ax, data, palette, title="Global"):explode = [0.08] * len(data) #饼图分裂效果start_angle = -240 #绘制的起始角度aspect_ratio = 0.5 #纵横比thickness_factor = 0.01 #每一层饼图的厚度因子for i in range(1, 35): #循环绘制34次饼图,模拟3D厚度ax_pie.pie(data, #数据colors=palette, #颜色explode=explode, #分裂属性startangle=start_angle, #起始角度radius=1.0, #半径counterclock=False, #顺时针绘制center=(0, -i * thickness_factor), #向下移动中心点以模拟厚度堆叠wedgeprops={'alpha': 1, 'edgecolor': 'none'}) #不透明且无边框_, _, autotexts = ax_pie.pie(data, #绘制最顶层的饼图colors=palette, #颜色explode=explode, #分裂属性startangle=start_angle, #起始角度autopct='%1.1f%%', #百分比显示格式pctdistance=0.7, #百分比标签距离圆心的距离counterclock=False, #顺时针绘制radius=1.0, #半径wedgeprops={'linewidth': 2.5, 'edgecolor': 'white'}) #扇形边缘为白色细线for text in autotexts:text.set_fontsize(18) #设置所有百分比文本的字体大小# 创建一个矩形对象作为外框rect = Rectangle((-1.25, -1.8), #左下角坐标2.4, #宽度3.5, #高度fill=False, #不填充颜色edgecolor='black', #边框颜色linewidth=2, #边框线宽transform=ax_pie.transData, #坐标系clip_on=False) #允许矩形超出坐标轴边界显示ax_pie.add_patch(rect) #将矩形添加到饼图坐标轴中#设置标题文本ax_pie.text(-1.2, # X坐标2.45 * aspect_ratio, #Y坐标(title, #内容fontweight='bold', #字体加粗fontsize=20, #字体大小transform=ax_pie.transData) #坐标系ax_pie.set_aspect(aspect_ratio) #应用纵横比设置ax_pie.axis('off') #隐藏刻度和边框

第四部分

# =========================================================================================# ====================================== 4. 主图绘制函数 =========================================# =========================================================================================def plot_analysis_by_scheme(scheme_id):current_colors = COLOR_SCHEMES[scheme_id] #获取颜色方案fig = plt.figure(figsize=(24, 20), dpi=120) # 创建画布a_left, a_right = 0.02, 0.70 #区域A(左侧)的左右边界位置比例b_left, b_right = 0.71, 0.98 #区域B(右侧)的左右边界位置比例title_h = 0.045 #标题栏的高度比例top_y = 1.05 #顶部的Y坐标基准# 设置左侧大标题的X坐标(居中)fig.text((a_left + a_right) / 2, #X坐标top_y + title_h / 2, #Y坐标"(A) Global & TOP 10 countries", #内容ha='center', #水平居中va='center', #垂直居中fontsize=30, #字体大小fontweight='bold', #字体加粗)# 设置右侧大标题的X坐标fig.text((b_left + b_right) / 2, #X坐标top_y + title_h / 2, #Y坐标"(B) Sectors", #标题文本ha='center', #水平对齐va='center', #垂直对齐fontsize=30, #字体大小fontweight='bold', #加粗)#创建大外框矩形main_border = Rectangle((a_left, 0.01),b_right - a_left, #宽度top_y + title_h - 0.05, #高度transform=fig.transFigure, #使用图形坐标系fill=False, #不填充edgecolor='black', #黑色边框linewidth=4, #线宽zorder=10)fig.patches.append(main_border) #添加外框到图形

第五部分

# 创建网格布局gs = gridspec.GridSpec(4, #行3, #列figure=fig, #归属于当前figurewidth_ratios=[1, 1, 0.8], #列宽比例left=0.07, #左边距right=0.975, #右边距bottom=0.06, #下边距top=top_y - 0.035, #上边距wspace=0.15, #子图水平间距hspace=0.15) #子图垂直间距years = [1990, 1995, 2000, 2005, 2010, 2015, 2020] #分析的年份列表for i, year in enumerate(years): #遍历每一年份进行绘图row, col = divmod(i, 2) #计算当前年份对应的网格行和列索引ax = fig.add_subplot(gs[row, col]) #在指定网格位置添加子图df = df_stacked[df_stacked['Year'] == year].sort_values('Total') #筛选当年数据并按总值排序for s_idx, s in enumerate(sectors):# 绘制水平条形图ax.barh(df['Country'], #Y轴df[s], # X轴left=left_vals, #条形的起始位置color=current_colors[s_idx], #颜色height=0.7) #条形高度left_vals += df[s] #更新左侧位置,为下一层堆叠做准备current_max = df['Total'].max() #获取当前数据的最大总值ax.set_xlim(0, current_max * 1.3) #设置X轴范围#设置子图标题ax.set_title(f"({chr(97 + i)}) {year}", #自动生成a, b, c序号loc='left', #左对齐fontsize=26, #字体大小fontweight='bold', #加粗pad=8) #标题与图表的间距ax.spines[['top', 'right']].set_visible(False) #隐藏顶部和右侧的边框轴ax.tick_params(direction='in', #刻度线向内labelsize=24) #刻度标签字体大小ax.set_xlabel('(Mt)', #X轴标签loc='right', #右fontsize=24) #字体大小for spine in ax.spines.values(): # 遍历所有边框轴spine.set_linewidth(3) #设置边框线draw_3d_pie(ax, global_shares, current_colors) #调用函数在当前子图中绘制3D饼图

第六部分

#在原有网格的第3列中创建嵌套网格gs_right = gridspec.GridSpecFromSubplotSpec(5, #行1, #列subplot_spec=gs[:, 2], #指定放置在gs的第3列所有行区域hspace=0.35) #垂直间距#遍历绘制右侧图表for i, sector_name inenumerate(sectors):ax_b = fig.add_subplot(gs_right[i]) #添加子图到右侧嵌套网格target_years = [1990, 2000, 2010, 2020] #定义右侧图表显示的特定年份color_b = current_colors[i] #颜色ax_b.set_title(sector_name, #子图标题loc='right', #右对齐fontsize=26, #字体大小pad=12) #间距sector_data = df_scatter[df_scatter['Sector'] == sector_name] #筛选数据for j, yr inenumerate(target_years): #遍历特定年份绘制箱型图元素vals = sector_data[sector_data['Year'] == yr]['Value'].values #获取当年数值iflen(vals) == 0: continue #如果无数据则跳过q1, median, q3 = np.percentile(vals, [25, 50, 75]) #计算四分位数和中位数low, high = np.min(vals), np.max(vals) #获取最小值和最大值box_w = 2.5 #设置箱体的一半宽度rect = Rectangle((yr - box_w, q1), #创建箱体矩形box_w, #宽度q3 - q1, #高度facecolor='none', #无填充颜色edgecolor=color_b, #边框颜色lw=3) #线宽ax_b.plot([yr, yr], #上须竖线X坐标[q3, high], #上须竖线Y坐标color=color_b, #颜色lw=3) #线宽ax_b.plot([yr - box_w, yr], #最大值横线X坐标[high, high], #最大值横线Y坐标color=color_b, #颜色lw=3) #线宽ax_b.plot([yr, yr], # 下须竖线X坐标[q1, low], #下须竖线Y坐标color=color_b, #颜色lw=3) #线宽ax_b.plot([yr - box_w, yr], #最小值横线X坐标[low, low], #最小值横线Y坐标color=color_b, #颜色lw=3) #线宽for spine in ax_b.spines.values(): #遍历边框spine.set_linewidth(3) #设置边框线宽x_jitter = yr + np.random.uniform(1, #生成散点图的X轴随机抖动1.5, #抖动范围size=len(vals)) #数量ax_b.scatter(x_jitter, #散点图X坐标vals, #Y坐标s=14, #点的大小color=color_b, #颜色marker='x', #标记形状alpha=0.8, #透明度lw=3) #线宽ax_b.scatter(yr, #均值点X坐标np.mean(vals), #均值点Y坐标color='black', #颜色s=25, #点的大小zorder=5)ax_b.set_xticks(target_years) #设置X轴刻度ax_b.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}')) #设置Y轴标签格式ax_b.tick_params(direction='in', #刻度向内labelsize=24) #刻度字体大小

第七部分

#分隔线ax_sep = plt.Line2D([b_left - 0.005, b_left - 0.005], #设置X坐标[0.01, top_y + title_h - 0.05], #Y坐标transform=fig.transFigure, #使用图形坐标系color='black', #黑色linestyle='--', #样式linewidth=4, #线宽zorder=11)fig.lines.append(ax_sep) #添加线条到图形fig.legend(handles, #图例句柄sectors, #图例文本loc='upper left', #图例位置bbox_to_anchor=(0.38, 0.28), #位置ncol=1, #列数frameon=False, #不显示图例边框fontsize=36, #字体大小title="Legend", #图例标题title_fontproperties={'weight': 'bold', 'size': 42},#图例标题属性alignment='left') #图例标题相对位置#保存save_png_path = r"plot_scheme_{}.png".format(scheme_id)save_pdf_path = r"plot_scheme_{}.pdf".format(scheme_id)plt.savefig(save_png_path, dpi=300, bbox_inches='tight')plt.savefig(save_pdf_path, bbox_inches='tight')

第八部分

# =========================================================================================# ======================================5.执行部分=========================================# =========================================================================================if __name__ == "__main__":file_path = r"data.xlsx" #文件路径df_stacked = pd.read_excel(file_path, sheet_name='StackedBarData') #读取堆叠柱状图数据df_scatter = pd.read_excel(file_path, sheet_name='SectorDistribution') #读取散点图数据sectors = ['Power Industry', 'Building', 'Transport', 'Other Industrial Combustion', 'Other Sectors'] # 定义分区scheme_index = 20 #颜色方案IDplot_analysis_by_scheme(scheme_index) #调用主绘图函数

如何应用到你自己的数据

1.设置原始数据文件的路径:
file_path = r"data.xlsx" #文件路径2.设置要读取的指定表的数据:
df_stacked = pd.read_excel(file_path, sheet_name='StackedBarData')df_scatter = pd.read_excel(file_path, sheet_name='SectorDistribution')
3.设置分区:
sectors = ['Power Industry', 'Building', 'Transport', 'Other Industrial Combustion', 'Other Sectors']4.设置颜色方案:
scheme_index = 20 #选择颜色方案ID5.设置绘图结果的保存地址:
save_png_path = r"plot_scheme_{}.png".format(scheme_id)save_pdf_path = r"plot_scheme_{}.pdf".format(scheme_id)

推荐


获取方式
