如何基于DataFrame用Matplotlib绘制以j、k为索引的3D柱状图?
3D柱状图优化实现方案
一、Matplotlib 优化实现
Matplotlib默认的3D柱状图确实容易显得杂乱,通过调整视角、柱体尺寸、配色和刻度等细节能大幅提升美观度:
import matplotlib.pyplot as plt import numpy as np import pandas as pd # 加载数据 data = pd.DataFrame({ 'j': [16,19,21,24,25,25,26,26,26,26,27,27,27,27], 'k': [36,40,52,41,37,45,31,36,42,47,30,35,36,38], 'z': [3.34541e-07,4.4038e-07,1.24715e-06,9.13244e-07,6.33979e-07,5.89413e-07,7.83958e-07,6.24651e-07,5.44847e-07,4.77851e-07,8.50074e-07,5.51727e-07,1.2272e-06,5.77199e-07] }) # 将非连续的j、k映射为连续坐标轴索引,避免柱体分散重叠 j_unique = np.unique(data['j']) k_unique = np.unique(data['k']) x = np.array([np.where(j_unique == val)[0][0] for val in data['j']]) y = np.array([np.where(k_unique == val)[0][0] for val in data['k']]) z = data['z'].values # 设置柱体宽度和深度,避免互相遮挡 dx = dy = 0.6 fig = plt.figure(figsize=(10,7)) ax = fig.add_subplot(111, projection='3d') # 用颜色映射区分柱体高度,增强可读性 colors = plt.cm.viridis(z / z.max()) ax.bar3d(x, y, np.zeros_like(z), dx, dy, z, color=colors) # 配置坐标轴标签与刻度,匹配原始j、k值 ax.set_xlabel('j') ax.set_xticks(np.arange(len(j_unique))) ax.set_xticklabels(j_unique) ax.set_ylabel('k') ax.set_yticks(np.arange(len(k_unique))) ax.set_yticklabels(k_unique) ax.set_zlabel('z') # 调整视角,找到最清晰的展示角度 ax.view_init(elev=30, azim=-60) # 隐藏多余网格和背景,让图表更简洁 ax.grid(False) ax.xaxis.pane.fill = False ax.yaxis.pane.fill = False ax.zaxis.pane.fill = False plt.tight_layout() plt.show()
二、Plotly 优化实现
Plotly的3D柱状图默认布局需要调整,通过自定义布局、hover信息和视角来优化展示效果:
import plotly.graph_objects as go import pandas as pd # 加载数据 data = pd.DataFrame({ 'j': [16,19,21,24,25,25,26,26,26,26,27,27,27,27], 'k': [36,40,52,41,37,45,31,36,42,47,30,35,36,38], 'z': [3.34541e-07,4.4038e-07,1.24715e-06,9.13244e-07,6.33979e-07,5.89413e-07,7.83958e-07,6.24651e-07,5.44847e-07,4.77851e-07,8.50074e-07,5.51727e-07,1.2272e-06,5.77199e-07] }) fig = go.Figure(data=[go.Bar3d( x=data['j'], y=data['k'], z=data['z'], width=0.8, depth=0.8, marker=dict( color=data['z'], colorscale='viridis', colorbar=dict(title='z值') ), # 自定义hover信息,方便查看完整数据 text=[f'j:{j}<br>k:{k}<br>z:{z:.2e}' for j,k,z in zip(data['j'], data['k'], data['z'])], hoverinfo='text' )]) fig.update_layout( scene=dict( xaxis_title='j', yaxis_title='k', zaxis_title='z', # 调整视角位置,确保所有柱体清晰可见 camera=dict(eye=dict(x=1.5, y=-1.5, z=0.8)), xaxis=dict(showgrid=False), yaxis=dict(showgrid=False), zaxis=dict(showgrid=False) ), width=800, height=600, margin=dict(l=0, r=0, b=0, t=0) ) fig.show()
内容的提问来源于stack exchange,提问作者Alberto Sciuto
相关产品推荐
相关产品推荐

