You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib 3D柱状图中清晰展示小数值

3D柱状图小数值可视化解决方案

你的问题核心是数据量级差异过大(最大值148+,最小值0.02+),导致小数值柱子被大数值挤压得几乎不可见。以下是几种实用的解决方案:

方案1:使用对数刻度(最推荐)

对数刻度可以压缩大数值的视觉占比,同时放大小数值的差异,让所有量级的数据都能清晰展示:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(10)

#data
time = [[148.64793017553907, 47.00162830693381, 1.3599472795213974, 1.0770502873829435, 0.2416407755443028, 0.051920437812805136],
        [100.7717864097111, 11.489065728868756, 0.5487183400562831, 0.12449462073189865, 0.15135425840105324, 0.030407779557364272],
        [10.223643741910418, 1.6037633759634835, 0.3846410546983991, 0.09999658720833912, 0.07089985779353546, 0.029794696399143727],
        [0.9271023046402703, 0.1371803828648158, 0.3223802804946899, 0.09767089911869589, 0.024286287171500026, 0.029627582005092024],
        [0.11088135128929497, 0.06808395726340152, 0.224113655090332, 0.08966402666909352, 0.022294637135096912, 0.029868837765284897]]

colors = ['r', 'g', 'b', 'y','m']
yticks = [1,2,3,4,5]
fig = plt.figure()
ax = fig.add_subplot(111 ,projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_yticks(yticks)

# 启用对数刻度,设置最小Z值避免log(0)错误
ax.set_zscale('log')
ax.set_zlim(bottom=0.01)

xs=np.array([1,2,3,4,5,6])
for i in range(5):
    ax.bar(xs, time[i], zs=i+1, zdir='y', color=colors[i], alpha=0.8)

plt.tight_layout()
plt.savefig("3d_log.png")
plt.show()

方案2:给柱子添加数值标签

直接在每个柱子顶部标注具体数值,不受视觉高度限制,清晰展示所有数据:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(10)

#data
time = [[148.64793017553907, 47.00162830693381, 1.3599472795213974, 1.0770502873829435, 0.2416407755443028, 0.051920437812805136],
        [100.7717864097111, 11.489065728868756, 0.5487183400562831, 0.12449462073189865, 0.15135425840105324, 0.030407779557364272],
        [10.223643741910418, 1.6037633759634835, 0.3846410546983991, 0.09999658720833912, 0.07089985779353546, 0.029794696399143727],
        [0.9271023046402703, 0.1371803828648158, 0.3223802804946899, 0.09767089911869589, 0.024286287171500026, 0.029627582005092024],
        [0.11088135128929497, 0.06808395726340152, 0.224113655090332, 0.08966402666909352, 0.022294637135096912, 0.029868837765284897]]

colors = ['r', 'g', 'b', 'y','m']
yticks = [1,2,3,4,5]
fig = plt.figure()
ax = fig.add_subplot(111 ,projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_yticks(yticks)

xs=np.array([1,2,3,4,5,6])
for i in range(5):
    bars = ax.bar(xs, time[i], zs=i+1, zdir='y', color=colors[i], alpha=0.8)
    # 给每个柱子添加数值标签,保留4位小数
    for bar, val in zip(bars, time[i]):
        x = bar.get_x() + bar.get_width()/2
        y = i+1
        z = val
        ax.text(x, y, z, f'{val:.4f}', ha='center', va='bottom')

plt.tight_layout()
plt.savefig("3d_labels.png")
plt.show()

方案3:拆分图表,分尺度展示

将大数值和小数值分组,分别绘制两个3D图,让每组数据都在合适的尺度下展示:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(10)

#data
time = [[148.64793017553907, 47.00162830693381, 1.3599472795213974, 1.0770502873829435, 0.2416407755443028, 0.051920437812805136],
        [100.7717864097111, 11.489065728868756, 0.5487183400562831, 0.12449462073189865, 0.15135425840105324, 0.030407779557364272],
        [10.223643741910418, 1.6037633759634835, 0.3846410546983991, 0.09999658720833912, 0.07089985779353546, 0.029794696399143727],
        [0.9271023046402703, 0.1371803828648158, 0.3223802804946899, 0.09767089911869589, 0.024286287171500026, 0.029627582005092024],
        [0.11088135128929497, 0.06808395726340152, 0.224113655090332, 0.08966402666909352, 0.022294637135096912, 0.029868837765284897]]

colors = ['r', 'g', 'b', 'y','m']
yticks = [1,2,3,4,5]

# 绘制大数值组(Y=1、2)
fig1 = plt.figure(figsize=(8,6))
ax1 = fig1.add_subplot(111, projection='3d')
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_zlabel('Z')
ax1.set_yticks([1,2])
xs=np.array([1,2,3,4,5,6])
for i in range(2):
    ax1.bar(xs, time[i], zs=i+1, zdir='y', color=colors[i], alpha=0.8)
plt.tight_layout()
plt.savefig("3d_large.png")

# 绘制小数值组(Y=3、4、5)
fig2 = plt.figure(figsize=(8,6))
ax2 = fig2.add_subplot(111, projection='3d')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_zlabel('Z')
ax2.set_yticks([3,4,5])
ax2.set_zlim(bottom=0, top=2)  # 聚焦小数值范围
for i in range(2,5):
    ax2.bar(xs, time[i], zs=i+1, zdir='y', color=colors[i], alpha=0.8)
plt.tight_layout()
plt.savefig("3d_small.png")

plt.show()

方案4:调整Z轴范围(仅关注小数值时使用)

如果只需要分析小数值的差异,可以手动设置Z轴上限,截断大数值柱子:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(10)

#data
time = [[148.64793017553907, 47.00162830693381, 1.3599472795213974, 1.0770502873829435, 0.2416407755443028, 0.051920437812805136],
        [100.7717864097111, 11.489065728868756, 0.5487183400562831, 0.12449462073189865, 0.15135425840105324, 0.030407779557364272],
        [10.223643741910418, 1.6037633759634835, 0.3846410546983991, 0.09999658720833912, 0.07089985779353546, 0.029794696399143727],
        [0.9271023046402703, 0.1371803828648158, 0.3223802804946899, 0.09767089911869589, 0.024286287171500026, 0.029627582005092024],
        [0.11088135128929497, 0.06808395726340152, 0.224113655090332, 0.08966402666909352, 0.022294637135096912, 0.029868837765284897]]

colors = ['r', 'g', 'b', 'y','m']
yticks = [1,2,3,4,5]
fig = plt.figure()
ax = fig.add_subplot(111 ,projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_yticks(yticks)

# 设置Z轴范围,聚焦小数值
ax.set_zlim(bottom=0, top=2)

xs=np.array([1,2,3,4,5,6])
for i in range(5):
    ax.bar(xs, time[i], zs=i+1, zdir='y', color=colors[i], alpha=0.8)

plt.tight_layout()
plt.savefig("3d_zoom.png")
plt.show()

内容的提问来源于stack exchange,提问作者HaYou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:19:59