
代码绘制成果展示










代码解释


第一部分

# =========================================================================================# ====================================== 1. 环境设置 =======================================# =========================================================================================import matplotlib.pyplot as pltimport matplotlib.patches as patchesimport matplotlib.lines as mlinesimport matplotlib.gridspec as gridspecimport pandas as pdimport numpy as npimport seaborn as snsimport osfrom scipy import statsimport matplotlibplt.rcParams['font.family'] = 'serif'plt.rcParams['font.serif'] = ['Times New Roman']plt.rcParams['axes.unicode_minus'] = Falsesns.set_context("notebook")sns.set_style("ticks")matplotlib.rcParams['pdf.fonttype'] = 42matplotlib.rcParams['ps.fonttype'] = 42

第二部分

# =========================================================================================# ======================================2.颜色库=======================================# =========================================================================================COLOR_SCHEMES = {# =================原有单色渐变/近似色系 (1-20)=================1: ["#405163", "#536D7A", "#688A90", "#8CB2A6", "#C4D8CB", "#40686A", "#959595", "#2F4F4F"],}scheme_index = 39 #当前使用的颜色方案CUSTOM_COLORS = COLOR_SCHEMES.get(scheme_index, COLOR_SCHEMES[1]) # 获取颜色列表OUTPUT_DIR = r'组合图' #结果输出路径FRAME_LINEWIDTH = 1.5 # 边框宽度

第三部分

# =========================================================================================# ======================================3.堆叠条形图绘制函数=======================================# =========================================================================================def render_panel_a(ax, df):df_sorted = df.sort_values("Total", ascending=True).reset_index(drop=True) # 将数据按列升序排序color_sig = CUSTOM_COLORS[5] #显著部分颜色color_ns = CUSTOM_COLORS[6] #非显著部分颜色y_pos = range(len(df_sorted)) # 生成Y轴的位置序列,长度等于数据行数# 绘制水平条形图ax.barh(y_pos,#位置df_sorted["Significant"], #数值color=color_sig, #颜色height=0.75, # 条形的高度label='Show a cooling effect') #图例标签# 绘制第二组水平条形图(堆叠部分)ax.barh(y_pos, #位置df_sorted["Not_Significant"], #数值left=df_sorted["Significant"], # 设置起始位置在显著条形的右侧,实现堆叠效果color=color_ns, # 颜色height=0.75, #条形的高度label='No significant cooling effect') #图例标签# 配置X轴的刻度参数ax.tick_params(axis='x',direction='out', # 刻度线朝外labelsize=22) # 字体大小# 配置Y轴的刻度参数ax.tick_params(axis='y',length=0, # 刻度线长度labelsize=22) # 字体大小box_height = 1 #顶部图框高度box_y_start = len(df_sorted) - 0.4 #灰色方框的起始Y坐标# 创建一个矩形rect = patches.Rectangle((0, box_y_start), # 起始坐标x_limit, # 矩形宽度box_height, # 矩形高度linewidth=1, # 边框线宽edgecolor='black', # 边框颜色facecolor='#A9A9A9', #填充颜色alpha=1, # 透明度clip_on=False) # 允许矩形超出坐标轴范围显示ax.add_patch(rect) # 将矩形添加到坐标轴上# 设置子图编号ax.text(-0.45, #X1.00, # Y'a', #内容transform=ax.transAxes, #相对坐标系fontsize=30, #字体大小fontweight='normal', # 字体粗细va='top', # 垂直对齐fontname='Times New Roman')ax.spines['top'].set_visible(False) # 隐藏顶部边框ax.spines['right'].set_visible(False) # 隐藏右侧边框

第四部分

bw_method 控制曲线的平滑的程度。填充密度曲线下方的区域,形成半个小提琴的形状。计算中位数,并在密度图上画一条白色的虚线,指示数据的中心位置


# =========================================================================================# ======================================4.半小提琴图绘制函数=======================================# =========================================================================================def draw_half_violin(ax, data, pos, color, width=0.5):density = stats.gaussian_kde(data, bw_method=0.08) # 使用高斯核密度估计计算数据的密度xs = np.linspace(min(data), max(data), 200) # 在数据最小值和最大值之间生成均匀分布的点作为X轴ys = density(xs) # 计算这些点对应的密度值作为Y轴ys = ys / ys.max() * width # 将密度值归一化并缩放到指定的宽度ax.vlines(median_val, # x轴坐标pos, # 垂直线的起始y坐标pos + median_height, # 垂直线的结束y坐标color='white', # 线条颜色linestyle='--', # 线条样式linewidth=1.2, # 线条宽度设alpha=1.0, # 透明度zorder=2)

第五部分

# =========================================================================================# ======================================5.云雨图绘制函数=======================================# =========================================================================================def render_panel_b(fig, gs_base, df):# 定义指标信息列表,包含名称、单位、X轴范围、X轴刻度metrics_info = [("PCM", "°C", (0, 7.5), [0, 1, 2, 3, 4, 5, 6, 7]),("PCD", "m", (0, 330), [0, 100, 200, 300]),("PCI", "", (0, 0.07), [0, 0.02, 0.04, 0.06]),("PCG", "", (0, 2.2), [0, 1, 2])]categories = ["Megacity", "Large City", "Medium City I", "Medium City II", "Small City"] # 定义区域分类列表categories_rev = categories[::-1] # 将分类列表反转y_positions = np.arange(len(categories)) # 生成Y轴位置索引color_map = {cat: col for cat, col in zip(categories, CUSTOM_COLORS[:5])} # 创建类别到颜色的映射字典if len(cat_data) == 0: # 如果没有数据,则跳过continuewidth=0.45) # 宽度# 绘制箱线图ax.boxplot([cat_data], # 数据positions=[y_base + 0.08], # 箱线图位置vert=False, # 水平方向widths=0.15, #箱体宽度patch_artist=True, # 填充颜色showfliers=False, # 不显示离群点showcaps=False, # 不显示箱线图的帽子medianprops={"color": "black", # 中位数线颜色"linewidth": 1}, # 中位数线宽boxprops={"facecolor": color, # 箱体填充颜色"edgecolor": "black", # 箱体边框颜色"linewidth": 1, # 箱体边框线宽"alpha": 0.8}, # 透明度whiskerprops={"color": "black", # 须线颜色"linewidth": 1}) # 须线宽度jitter = np.random.uniform(-0.15, 0.0, size=len(cat_data)) # 生成随机抖动值median_bg_color = CUSTOM_COLORS[7] # 获取用于散点的颜色# 绘制散点图ax.scatter(cat_data, # x轴数据y_base + jitter - 0.05, # y轴数据s=6, # 散点的大小color=median_bg_color, # 散点的颜色alpha=0.5, # 透明度zorder=0)# 设置子图标题ax.set_title(metric, #名称fontsize=20, #字体大小pad=10, # 标题距离fontweight='bold') #加粗#设置X轴标签单位ax.set_xlabel(unit,loc='right',labelpad=-16, fontweight='bold', fontname='Times New Roman',fontsize=22)ax.set_xlim(xlim) # X轴范围ax.set_yticklabels(categories_rev, fontsize=22) # 显示类别名称作为Y轴标签ax.tick_params(axis='y', length=0) # Y轴刻度线长度ax.spines['left'].set_visible(False) # 隐藏图框ax.spines['top'].set_visible(False) # 隐藏顶部图框ax.spines['right'].set_visible(False) # 隐藏右侧图框ax.spines['bottom'].set_visible(True) # 显示底部图框# 显示网格线ax.grid(axis='x', # X轴color='lightgrey', # 网格线颜色linestyle='-', # 网格线样式linewidth=0.5, # 网格线alpha=0.5) # 网格线pass

第六部分

# =========================================================================================# ======================================6.箱线图绘制函数=======================================# =========================================================================================def render_panel_c(fig, gs_base, df, cities):# 创建子网格布局gs_c = gridspec.GridSpecFromSubplotSpec(1, #行2, #列subplot_spec=gs_base, # 基于基础网格width_ratios=[1, 2.4], # 左右列宽度比例wspace=0.1) # 水平间距ax_text = fig.add_subplot(gs_c[0]) # 在左侧网格添加子图用于显示文本和图例ax_text.axis('off') # 关闭坐标轴显示# 设置子图编号ax_text.text(-0.05, #X1.02, # Y'c', # 文本内容fontsize=28, # 字体大小fontweight='normal', # 字体粗细transform=ax_text.transAxes, # 使用相对坐标系fontname='Times New Roman')#图例内容设置col_1 = ["01.Shanghai", "02.Hangzhou", "03.Nanjing", "04.Suzhou", "05.Hefei", "06.Ningbo", "07.Wuxi","08.Changzhou", "09.Shaoxing"]col_2 = ["10.Nantong", "11.Yangzhou", "12.Yancheng", "13.Tāizhou", "14.Wuhu", "15.Jiaxing", "16.Tàizhou","17.Ma'anshan", "18.Zhenjiang"]col_3 = ["19.Jinhua", "20.Huzhou", "21.Anqing", "22.Zhoushan", "23.Tongling", "24.Chuzhou", "25.Chizhou","26.Xuancheng"]all_cols = [col_1, col_2, col_3] #合成一个列表col_x_positions = [0.0, 0.35, 0.70] #设置三列的X坐标位置for col_idx, city_list in enumerate(all_cols): # 遍历每一列x_pos = col_x_positions[col_idx] # 获取当前列的X坐标for row_idx, city_name in enumerate(city_list): # 遍历当前列的每一个元素y_pos = 0.98 - row_idx * 0.055 #Y坐标# 在指定位置绘制文本ax_text.text(x_pos, # X坐标y_pos, # Y坐标city_name, # 内容fontsize=22, # 字体大小transform=ax_text.transAxes, # 使用相对坐标ha='left') # 左对齐legend_start_y = 0.35 # 设置图例部分的起始Y坐标legend_gap_y = 0.07 # 设置图例条目间的垂直间距text_offset_x = 0.12 # 设置图例文字的X轴偏移量cat_names = ["Megacity", "Large City", "Medium City I", "Medium City II", "Small City"] # 类别名称列表# =======================================================# ======================颜色图例==========================# =======================================================legend_right_x = 0.55 # 右侧图例的起始X坐标legend_right_text_offset = 0.12 # 右侧图例文字的偏移量for i, (name, color) in enumerate(zip(cat_names, CUSTOM_COLORS[:5])): # 遍历类别和对应的颜色y_loc = legend_start_y - i * legend_gap_y # 计算当前条目的Y坐标# 绘制颜色矩形块ax_text.add_patch(patches.Rectangle((legend_right_x, y_loc), #坐标0.1, # 宽度0.04, # 高度facecolor=color, # 填充颜色edgecolor='none', #无边框transform=ax_text.transAxes)) # 使用相对坐标# 绘制类别名称文本ax_text.text(legend_right_x + legend_right_text_offset, # xy_loc + 0.02, # Yname, # 名称transform=ax_text.transAxes, # 使用相对坐标fontsize=22, # 字体大小va='center') # 垂直居中# =======================================================# ======================25-75图例图例==========================# =======================================================y1 = legend_start_y # Y坐标# 绘制白色矩形ax_text.add_patch(patches.Rectangle((0.0, y1), # 坐标0.1, # 宽度0.04, # 高度facecolor='white', # 填充edgecolor='black', #边框linewidth=1.2, # 线宽transform=ax_text.transAxes)) # 相对坐标# 绘制说明文本ax_text.text(text_offset_x, #xy1 + 0.02, # Y"25%-75%", # 文本transform=ax_text.transAxes, # 相对坐标fontsize=22, # 字体大小va='center') # 垂直居中# =======================================================# ======================中值线图例图例==========================# =======================================================y2 = y1 - legend_gap_y # Y坐标median_bg_color = CUSTOM_COLORS[7] # 获取颜色# 线宽transform=ax_text.transAxes) # 相对坐标ax_text.add_line(line_white) # 将线条添加到子图ax_text.text(text_offset_x, # 绘制说明文本y2 + 0.02, # Y坐标"Median Line", # 文本内容transform=ax_text.transAxes, # 相对坐标fontsize=22, # 字体大小va='center') # 垂直居中# =======================================================# ======================均值图例图例==========================# =======================================================y3 = y2 - legend_gap_y # Y坐标# 绘制散点ax_text.scatter([0.05], # x[y3 + 0.02], # Y[y4 + 0.02, y4 + 0.02], # Ycolor='black', # 颜色linewidth=1.2, # 线宽transform=ax_text.transAxes) # 相对坐标ax_text.add_line(line_range) # 添加线条# 左侧垂直短线ax_text.add_line(mlines.Line2D([0.0, 0.0], # X坐标[y4 + 0.005, y4 + 0.035], # Y坐标color='black', # 颜色linewidth=1.2, # 线宽transform=ax_text.transAxes)) # 相对坐标# 右侧垂直短线ax_text.add_line(mlines.Line2D([0.1, 0.1], # X坐标[y4 + 0.005, y4 + 0.035], # Y坐标范围color='black', # 颜色linewidth=1.2, # 线宽transform=ax_text.transAxes)) # 相对坐标ax_text.text(text_offset_x, # Xy5 + 0.02, # Y坐标"Connecting line Mean", # 文本内容transform=ax_text.transAxes, # 相对坐标fontsize=22, # 字体大小va='center') # 垂直居中# 创建图表部分的子网格gs_plots = gridspec.GridSpecFromSubplotSpec(2, # 行2, # 列subplot_spec=gs_c[1], # 基于右侧网格wspace=0.15, # 水平间距hspace=0.2) # 垂直间距# 定义指标信息列表metrics = [("PCM", "PCM(°C)", (0, 9)),("PCD", "PCD(m)", (0, 350)),("PCI", "PCI", (0, 0.065)),("PCG", "PCG", (0, 2.5))]palette=palette, #颜色hue='City_ID', # 按照ID着色legend=False, # 不显示图例width=0.7, # 箱体宽度linewidth=0.8, # 线宽fliersize=1, # 离群点大小showfliers=False, # 不显示离群点boxprops=dict(alpha=0.9, # 透明度edgecolor='white'), # 边框颜色medianprops=dict(color='white', # 中位数线颜色linewidth=1)) # 中位数线宽ax.tick_params(axis='x', length=0) # 去掉X轴刻度线ax.tick_params(axis='y', length=0, labelsize=22) # 去掉Y轴刻度线for spine in ax.spines.values(): # 遍历所有图框spine.set_visible(True); # 显示图框spine.set_color('black'); # 设置图框颜色spine.set_linewidth(FRAME_LINEWIDTH) # 设置图框线宽

第七部分

# =========================================================================================# ======================================7.组合图绘制函数=======================================# =========================================================================================def draw_combined_figure(df_a, df_b, df_c, cities_c):fig = plt.figure(figsize=(30, 24)) # 创建画布,# 创建主网格main_gs = gridspec.GridSpec(2, # 行1, # 列figure=fig, # 画布height_ratios=[1.2, 1], # 高度比例hspace=0.1) # 垂直间距# 创建顶部子网格top_gs = gridspec.GridSpecFromSubplotSpec(1, #行2, # 列subplot_spec=main_gs[0], # 位于主网格第0行width_ratios=[1, 2.5], # 宽度比例wspace=0.1) # 水平间距ax_a = fig.add_subplot(top_gs[0]) # 在顶部左侧添加子图A1.02, # Y坐标'b', # 文本transform=ax_b_proxy.transAxes, # 相对坐标fontsize=28, # 字体大小fontweight='normal', # 字体粗细va='top', # 顶部对齐fontname='Times New Roman')ax_b_proxy.axis('off')render_panel_c(fig, main_gs[1], df_c, cities_c) # 绘制图Cplt.subplots_adjust(left=0.07, right=0.98, top=0.96, bottom=0.04) # 调整画布的边距#保存out_png = os.path.join(OUTPUT_DIR, f'Figure_Combined_Scheme_{scheme_index}.png')out_pdf = os.path.join(OUTPUT_DIR, f'Figure_Combined_Scheme_{scheme_index}.pdf')plt.savefig(out_png, dpi=300)plt.savefig(out_pdf)

第八部分

# =========================================================================================# ======================================8.子图保存函数=======================================# =========================================================================================def save_individual_figures(df_a, df_b, df_c, cities_c):fig_a, ax_a = plt.subplots(figsize=(10, 15)) # 创建图A的画布和轴render_panel_a(ax_a, df_a) # 绘制图Aplt.tight_layout() # 调整布局# 保存fig_a.savefig(os.path.join(OUTPUT_DIR, f'Figure_A_Scheme_{scheme_index}.png'), dpi=300)plt.close(fig_a)fig_b = plt.figure(figsize=(18, 12)) # 创建图B的画布gs_b = gridspec.GridSpec(1, 1)[0] # 创建图B的网格render_panel_b(fig_b, gs_b, df_b) # 绘制图Bfig_b.text(0.02, # X坐标0.95, # Y坐标'b', # 文本fontsize=28, # 字体大小fontweight='normal', # 字体粗细fontname='Times New Roman')plt.tight_layout() # 调整布局# 保存fig_b.savefig(os.path.join(OUTPUT_DIR, f'Figure_B_Scheme_{scheme_index}.png'), dpi=300)plt.close(fig_b)fig_c = plt.figure(figsize=(25, 12)) # 创建图C的画布gs_c = gridspec.GridSpec(1, 1)[0] # 创建图C的网格render_panel_c(fig_c, gs_c, df_c, cities_c) # 绘制图Cplt.tight_layout() # 调整布局# 保存fig_c.savefig(os.path.join(OUTPUT_DIR, f'Figure_C_Scheme_{scheme_index}.png'), dpi=300)plt.close(fig_c)

第九部分

# =========================================================================================# ======================================9.子图保存函数=======================================# =========================================================================================if __name__ == "__main__":# 读取数据df_a = pd.read_excel(r'data_a.xlsx')df_b = pd.read_excel(r'data_b.xlsx')df_c = pd.read_excel(r'data_c.xlsx')# 定义信息列表,包含ID、名称和类别索引cities_c = [(1, "Shanghai", 0), (2, "Hangzhou", 1), (3, "Nanjing", 1),(4, "Suzhou", 2), (5, "Hefei", 2), (6, "Ningbo", 2), (7, "Wuxi", 2), (8, "Changzhou", 2), (9, "Shaoxing", 2),(10, "Nantong", 3), (11, "Yangzhou", 3), (12, "Yancheng", 3), (13, "Taizhou", 3), (14, "Wuhu", 3),(15, "Jiaxing", 4), (16, "Taizhou", 4), (17, "Ma'anshan", 4), (18, "Zhenjiang", 4), (19, "Jinhua", 4),(20, "Huzhou", 4), (21, "Anqing", 4), (22, "Zhoushan", 4), (23, "Tongling", 4), (24, "Chuzhou", 4),(25, "Chizhou", 4), (26, "Xuancheng", 4)]draw_combined_figure(df_a, df_b, df_c, cities_c) # 执行绘制组合图函数save_individual_figures(df_a, df_b, df_c, cities_c) # 执行子图保存函数

如何应用到你自己的数据

1.设置颜色方案:
scheme_index = 39 #当前使用的颜色方案2.设置绘图结果的保存地址:
OUTPUT_DIR = r'组合图' #结果输出路径3.读取原始数据:
df_a = pd.read_excel(r'data_a.xlsx')
推荐


获取方式
