COLOR_SCHEMES = { 1: ['#0055D4', '#00C4FF', '#A3D8FF', '#E6E6E6', '#FFB78C', '#FF7F50', '#D62728'], 2: ['#8C510A', '#D8B365', '#F6E8C3', '#F5F5F5', '#C7EAE5', '#5AB4AC', '#01665E'], 3: ['#B2182B', '#EF8A62', '#FDDBC7', '#F7F7F7', '#D1E5F0', '#67A9CF', '#2166AC'], 4: ['#762A83', '#AF8DC3', '#E7D4E8', '#F7F7F7', '#D9F0D3', '#7FBF7B', '#1B7837'], 5: ['#B35806', '#F1A340', '#FEE0B6', '#F7F7F7', '#D8DAEB', '#998EC3', '#542788'], 6: ['#C51B7D', '#E9A3C9', '#FDE0EF', '#F7F7F7', '#E6F5D0', '#A1D76A', '#4D9221'], 7: ['#D73027', '#FC8D59', '#FEE090', '#FFFFBF', '#E0F3F8', '#91BFDB', '#4575B4'], 8: ['#006837', '#31A354', '#78C679', '#C2E699', '#FFFFCC', '#FFEDA0', '#FEB24C'], 9: ['#08589E', '#2B8CBE', '#4EB3D3', '#7BCCC4', '#A8DDB5', '#CCEBC5', '#F0F9E8'], 10: ['#990000', '#D7301F', '#EF6548', '#FC8D59', '#FDBB84', '#FDD49E', '#FEF0D9'], 11: ['#3F007D', '#54278F', '#6A51A3', '#807DBA', '#9E9AC8', '#BCBDDC', '#DADAEB'], 12: ['#000000', '#252525', '#525252', '#737373', '#969696', '#BDBDBD', '#D9D9D9'], 13: ['#49006A', '#7A0177', '#AE017E', '#DD3497', '#F768A1', '#FA9FB5', '#FCC5C0'], 14: ['#084081', '#0868AC', '#2B8CBE', '#4EB3D3', '#7BCCC4', '#A8DDB5', '#CCEBC5'], 15: ['#8C2D04', '#CC4C02', '#EC7014', '#FE9929', '#FEC44F', '#FEE391', '#FFFFD4'], 16: ['#E4572E', '#29335C', '#F3A712', '#A8C686', '#669BBC', '#E09F3E', '#9E2A2B'], 17: ['#FF007F', '#00F0FF', '#FFEA00', '#8A2BE2', '#00FF7F', '#FF4500', '#191970'], 18: ['#5E81AC', '#81A1C1', '#88C0D0', '#8FBCBB', '#BF616A', '#D08770', '#EBCB8B'], 19: ['#FF3B30', '#FF9500', '#FFCC00', '#4CD964', '#5AC8FA', '#007AFF', '#5856D6'], 20: ['#4A2511', '#8C3A00', '#D96C06', '#F2A007', '#F2D06B', '#A69E8D', '#59604C'], 21: ['#FFB3BA', '#FFDFBA', '#FFFFBA', '#BAFFC9', '#BAE1FF', '#D3B1FF', '#FFB1E6'], 22: ['#1A1A1D', '#4E4E50', '#6F2232', '#950740', '#C3073F', '#F0A07C', '#F2E8CF'], 23: ['#05668D', '#028090', '#00A896', '#02C39A', '#F0F3BD', '#FFB563', '#FF8166'], 24: ['#332E28', '#66594C', '#998675', '#CCBAA3', '#F2E6D8', '#40593A', '#8C2E2E'], 25: ['#FDF500', '#00FF41', '#008F11', '#00B8FF', '#FF003C', '#D400FF', '#2700FF'], 26: ['#264653', '#2A9D8F', '#E9C46A', '#F4A261', '#E76F51', '#8AB17D', '#B23A48'], 27: ['#D9ED92', '#B5E48C', '#99D98C', '#76C893', '#168AAD', '#1A759F', '#184E77'], 28: ['#001219', '#005F73', '#0A9396', '#94D2BD', '#E9D8A6', '#EE9B00', '#CA6702'], 29: ['#FF595E', '#FFCA3A', '#8AC926', '#1982C4', '#6A4C93', '#F4A261', '#E76F51'], 30: ['#22223B', '#4A4E69', '#9A8C98', '#C9ADA7', '#F2E9E4', '#D4A373', '#FAEDCD'], 31: ['#FF9F1C', '#FFBF69', '#FFFFFF', '#CBF3F0', '#2EC4B6', '#E71D36', '#011627'], 32: ['#000000', '#14213D', '#FCA311', '#E5E5E5', '#FFFFFF', '#D90429', '#EF233C'], 33: ['#8ECAE6', '#219EBC', '#023047', '#FFB703', '#FB8500', '#8A817C', '#463F3A'], 34: ['#CCD5AE', '#E9EDC9', '#FEFAE0', '#FAEDCD', '#D4A373', '#606C38', '#283618'], 35: ['#03045E', '#0077B6', '#00B4D8', '#90E0EF', '#CAF0F8', '#FFB703', '#FB8500'], 36: ['#0B090A', '#161A1D', '#660708', '#A4161A', '#BA1826', '#E5383B', '#F5F3F4'], 37: ['#F94144', '#F3722C', '#F8961E', '#F9C74F', '#90BE6D', '#43AA8B', '#577590'], 38: ['#540D6E', '#EE4266', '#FFD23F', '#3BCEAC', '#0EAD69', '#118AB2', '#073B4C'], 39: ['#10002B', '#240046', '#3C096C', '#5A189A', '#7B2CBF', '#9D4EDD', '#C77DFF'], 40: ['#E63946', '#F1FAEE', '#A8DADC', '#457B9D', '#1D3557', '#F4A261', '#E76F51'], 41: ['#003049', '#D62828', '#F77F00', '#FCBF49', '#EAE2B7', '#7F4F24', '#582F0E'], 42: ['#2B2D42', '#8D99AE', '#EDF2F4', '#EF233C', '#D90429', '#6D6875', '#B5838D'], 43: ['#780000', '#C1121F', '#FDF0D5', '#003049', '#669BBC', '#4A4E69', '#22223B'], 44: ['#355070', '#6D597A', '#B56576', '#E56B6F', '#EAAC8B', '#FFB4A2', '#FFCDB2'], 45: ['#F72585', '#7209B7', '#3A0CA3', '#4361EE', '#4CC9F0', '#00F5D4', '#9D4EDD'], 46: ['#FFCDB2', '#FFB4A2', '#E5989B', '#B5838D', '#6D6875', '#355070', '#1D3557'], 47: ['#2F3E46', '#354F52', '#52796F', '#84A98C', '#CAD2C5', '#F2E9E4', '#C9ADA7'], 48: ['#112A46', '#1A4301', '#247B7B', '#78A1BB', '#BFE2C7', '#EFCB68', '#AE3131'], 49: ['#001524', '#15616D', '#FFECD1', '#FF7D00', '#78290F', '#B39BC8', '#F1D8C1'], 50: ['#386641', '#6A994E', '#A7C957', '#F2E8CF', '#BC4749', '#3D348B', '#7678ED'], 51: ['#F9A03F', '#F7D002', '#F2ED6F', '#CFE0C3', '#9EC1A3', '#70A9A1', '#40798C'], 52: ['#390099', '#9E0059', '#FF0054', '#FF5400', '#FFBD00', '#3A0CA3', '#4CC9F0'], 53: ['#CDB4DB', '#FFC8DD', '#FFAFCC', '#BDE0FE', '#A2D2FF', '#83C5BE', '#006D77'], 54: ['#ED6A5A', '#F4F1DE', '#F2CC8F', '#E07A5F', '#3D405B', '#81B29A', '#7A9E9F'], 55: ['#0D3B66', '#FAF0CA', '#F4D35E', '#EE964B', '#F95738', '#8B2635', '#482C3D'], 56: ['#0F4C5C', '#E5989B', '#B5838D', '#6D6875', '#B8B8FF', '#9381FF', '#F8F7FF'], 57: ['#3A5A40', '#588157', '#A3B18A', '#DAD7CD', '#D4A373', '#FAEDCD', '#FEFAE0'], 58: ['#0466C8', '#0353A4', '#023E8A', '#002855', '#001845', '#001233', '#33415C'], 59: ['#283618', '#606C38', '#DDA15E', '#BC6C25', '#FEFAE0', '#E9EDC9', '#CCD5AE'], 60: ['#E29578', '#FFDDD2', '#EDF6F9', '#83C5BE', '#006D77', '#003049', '#D62828']}
import numpy as npimport matplotlib.pyplot as pltfrom matplotlib import rcParamsimport matplotlib.patches as mpatchesimport pandas as pdimport matplotlibimport osmatplotlib.rcParams['pdf.fonttype'] = 42matplotlib.rcParams['ps.fonttype'] = 42plt.rcParams['font.family'] = 'Times New Roman'plt.rcParams['font.weight'] = 'bold'plt.rcParams['axes.labelweight'] = 'bold'plt.rcParams['axes.titleweight'] = 'bold'COLOR_SCHEMES = { 7: ['#D73027', '#FC8D59', '#FEE090', '#FFFFBF', '#E0F3F8', '#91BFDB', '#4575B4'],}color_scheme_id = 7colors = COLOR_SCHEMES[color_scheme_id][::-1]def plot_formatted_3d_bars(data, error_data, x_labels, y_labels, colors): # 自动创建保存文件夹 save_dir = "图表" if not os.path.exists(save_dir): os.makedirs(save_dir) num_y, num_x = data.shape X, Y = np.meshgrid(np.arange(num_x), np.arange(num_y)) X = X.flatten() Y = Y.flatten() Z = np.zeros_like(X) dx_val = 0.5 dy_val = 0.65 dx = dx_val * np.ones_like(X) dy = dy_val * np.ones_like(Y) dz = data.flatten() color_list = [] for i in range(num_y): color_list.extend([colors[i]] * num_x) fig = plt.figure(figsize=(14, 8), dpi=150) ax = fig.add_subplot(111, projection='3d') ax.bar3d(X, Y, Z, dx, dy, dz, color=color_list, alpha=0.9, shade=True) for i in range(num_y): for j in range(num_x): x_pos = j + dx_val / 2 y_pos = i + dy_val / 2 z_pos = data[i, j] err = error_data[i, j] ax.plot([x_pos, x_pos], [y_pos, y_pos], [z_pos, z_pos + err], color='black', linewidth=1, zorder=10) cap_width = 0.12 ax.plot([x_pos - cap_width, x_pos + cap_width], [y_pos, y_pos], [z_pos + err, z_pos + err], color='black', linewidth=1, zorder=10) ax.text(x_pos, y_pos, z_pos + err + 1.5, str(int(z_pos)), color='black', ha='center', va='bottom', fontweight='bold', fontsize=10, zorder=10) ax.set_xticks(np.arange(num_x) + dx_val / 2) ax.set_xticklabels(x_labels, rotation=30, ha='right', va='center', fontsize=12) ax.tick_params(axis='x', pad=8) ax.set_yticks(np.arange(num_y) + dy_val / 2) ax.set_yticklabels(y_labels, fontsize=12) ax.tick_params(axis='y', pad=5) ax.set_zlabel('Species', fontsize=16, fontweight='bold', labelpad=15) ax.grid(False) ax.xaxis.pane.fill = False ax.yaxis.pane.fill = False ax.zaxis.pane.fill = False ax.xaxis.pane.set_edgecolor('none') ax.yaxis.pane.set_edgecolor('none') ax.zaxis.pane.set_edgecolor('none') ax.xaxis.line.set_color('black') ax.yaxis.line.set_color('black') ax.zaxis.line.set_color('black') ax.zaxis._axinfo['juggled'] = (1, 2, 2) ax.view_init(elev=20, azim=-55) ax.set_box_aspect(aspect=(2.5, 1.5, 1)) legend_patches = [mpatches.Patch(color=colors[i], label=y_labels[i]) for i in range(num_y)] ax.legend(handles=legend_patches, loc='upper right', bbox_to_anchor=(0.9, 0.8), frameon=False, fontsize=12) plt.subplots_adjust(left=0.05, right=0.85, bottom=0.15, top=0.95) # 仅保存PNG png_path = os.path.join(save_dir, f'3d_bar_chart{color_scheme_id}.png') plt.savefig(png_path, dpi=300, bbox_inches='tight') plt.close()if __name__ == '__main__': file_path = "data.xlsx" df_data = pd.read_excel(file_path, sheet_name='Mean_Data', index_col=0) df_error = pd.read_excel(file_path, sheet_name='Error_Data', index_col=0) x_labels = df_data.columns.tolist() y_labels = df_data.index.tolist() data = df_data.values error_data = df_error.values plot_formatted_3d_bars(data, error_data, x_labels, y_labels, colors)