【问题标题】:How to plot barplot 3D projection in matplotlib for multiple columns如何在matplotlib中为多列绘制barplot 3D投影
【发布时间】:2021-05-16 23:16:35
【问题描述】:

我有一个表格,其中包含根据两个不同参数的三个不同时间特征。我想在 x 和 y 轴上绘制这些参数,并在 z 轴上显示三个不同时间的条形图。我创建了一个简单的条形图,在其中绘制了一个时间特征:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

columns = ['R','Users','A','B','C']

df=pd.DataFrame({'R':[2,2,2,4,4,4,6,6,6,8,8],
              'Users':[80,400,1000,80,400,1000,80,400,1000,80,400],
              'A':[ 0.05381,0.071907,0.08767,0.04493,0.051825,0.05295,0.05285,0.0804,0.0967,0.09864,0.1097],
             'B':[0.04287,0.83652,5.49683,0.02604,.045599,2.80836,0.02678,0.32621,1.41399,0.19025,0.2111],
                'C':[0.02192,0.16217,0.71645, 0.25314,5.12239,38.92758,1.60807,262.4874,8493,11.6025,6288]},
                 columns=columns)



fig = plt.figure()
ax = plt.axes(projection="3d")

num_bars = 11
x_pos = df["R"]
y_pos = df["Users"]
z_pos = [0] * num_bars
x_size = np.ones(num_bars)/4
y_size = np.ones(num_bars)*50
z_size = df["A"]

ax.bar3d(x_pos, y_pos, z_pos, x_size, y_size, z_size, color='aqua')
plt.show()

这会产生一个简单的 3d 条形图:

但是,我想在现有的旁边为其余两列(B 和 C)以不同的颜色绘制类似的条形图,并添加一个图例。我不知道如何实现这一点。

作为一个附带问题,是否也可以仅在 x 轴和 y 轴上显示 df 的值?值是 2-4-6-8 和 80-400-1000,我不希望 pyplot 在这些轴上添加其他值。

【问题讨论】:

  • 您希望如何处理您的数据点跨越非常大的范围这一事实?如果您只是按照给定的值绘制值,那么非常大的值(例如 8493)将隐藏所有小的值(例如 0.02192)。
  • @DavidM。我知道这一点,我可能会在解决此问题后将其更改为对数刻度

标签: python matplotlib 3d bar-chart


【解决方案1】:

我自己设法找到了解决方案。为了解决值问题,我在所有时间都添加了一个(以避免负对数)并在所有时间列上使用np.log。以这种方式,这些值的范围为 0-10,并且情节变得更容易阅读。之后,我使用循环遍历每一列并创建相应的值、位置和颜色,并将它们全部添加到一个列表中。我为每一列移动了y_pos,因此这些列不会绘制在同一位置。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

columns = ['R','Users','A','B','C']

df=pd.DataFrame({'R':[2,2,2,4,4,4,6,6,6,8,8],
              'Users':[80,400,1000,80,400,1000,80,400,1000,80,400],
              'A':[ 0.05381,0.071907,0.08767,0.04493,0.051825,0.05295,0.05285,0.0804,0.0967,0.09864,0.1097],
             'B':[0.04287,0.83652,5.49683,0.02604,.045599,2.80836,0.02678,0.32621,1.41399,0.19025,0.2111],
                'C':[0.02192,0.16217,0.71645, 0.25314,5.12239,38.92758,1.60807,262.4874,8493,11.6025,6288]},
                 columns=columns)

fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection="3d")

df["A"] = np.log(df["A"]+1)
df["B"] = np.log(df["B"]+1)
df["C"] = np.log(df["C"]+1)

colors = ['r', 'g', 'b']

num_bars = 11
x_pos = []
y_pos = []
x_size = np.ones(num_bars*3)/4
y_size = np.ones(num_bars*3)*50
c = ['A','B','C']
z_pos = []
z_size = []
z_color = []
for i,col in enumerate(c):
    x_pos.append(df["R"])
    y_pos.append(df["Users"]+i*50)
    z_pos.append([0] * num_bars)
    z_size.append(df[col])
    z_color.append([colors[i]] * num_bars)
    
x_pos = np.reshape(x_pos,(33,))
y_pos = np.reshape(y_pos,(33,))
z_pos = np.reshape(z_pos,(33,))
z_size = np.reshape(z_size,(33,))
z_color = np.reshape(z_color,(33,))

ax.bar3d(x_pos, y_pos, z_pos, x_size, y_size, z_size, color=z_color)

plt.xlabel('R')
plt.ylabel('Users')
ax.set_zlabel('Time')

from matplotlib.lines import Line2D

legend_elements = [Line2D([0], [0], marker='o', color='w', label='A',markerfacecolor='r', markersize=10),
                  Line2D([0], [0], marker='o', color='w', label='B',markerfacecolor='g', markersize=10),
                   Line2D([0], [0], marker='o', color='w', label='C',markerfacecolor='b', markersize=10)
                  ]
                   
# Make legend
ax.legend(handles=legend_elements, loc='best')
# Set view
ax.view_init(elev=35., azim=35)
plt.show()

最终剧情:

【讨论】:

    猜你喜欢
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    相关资源
    最近更新 更多