【问题标题】:How to create a histogram where each bar is a heatmap of the corresponding bin?如何创建一个直方图,其中每个条形图都是相应 bin 的热图?
【发布时间】:2021-02-12 08:42:19
【问题描述】:

我有一个数据框:

df.head()[['price', 'volumen']]

    price   volumen
48  45      3
49  48      1
50  100     2
51  45      1
52  56      1

它表示具有特定价格的对象的数量。 我根据volume 列创建了一个直方图:

我想添加有关每个箱的价格分布的信息。我的想法是使用热图而不是单色列。例如。红色代表高价,黄色代表低价。

这是一个示例图来说明总体思路:

【问题讨论】:

  • 这是一个任务,而不是一个问题。甚至不是一个定义明确的任务。如何定义低价和高价?你的编码方法是什么,它在哪里失败了? Similar questions have 还有been asked before. 你有没有尝试实现它们?
  • @Mr.T 我想在一个箱子里有多种颜色。颜色应代表其中的价格范围
  • @JohanC 我看到了。如果我理解正确,它会创建标准热图,我会寻找不同的东西
  • 为什么它在一个酒吧里会有不同的颜色?据我了解您的问题,x 轴代表价格。
  • @Mr.T 不,它应该是直方图,所以 x 轴代表我在 volumen 列中有多少对象。此直方图基于代码 df['volumen'].plot.hist() 。所以我想添加每个箱子里面关于价格的表示。

标签: python pandas matplotlib seaborn


【解决方案1】:

以下示例使用 seaborn 的 Tips 数据集。通过将total_bill 分组到 bin 中来创建直方图。然后根据每组中的提示对条进行着色。

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import matplotlib.patches as mpatches
import seaborn as sns

sns.set_theme(style='white')
tips = sns.load_dataset('tips')
tips['bin'] = pd.cut(tips['total_bill'], 10)  # histogram bin

grouped = tips.groupby('bin')

min_tip = tips['tip'].min()
max_tip = tips['tip'].max()
cmap = 'RdYlGn_r'
fig, ax = plt.subplots(figsize=(12, 4))
for bin, binned_df in grouped:
    bin_height = len(binned_df)
    binned_tips = np.sort(binned_df['tip']).reshape(-1, 1)
    ax.imshow(binned_tips, cmap=cmap, vmin=min_tip, vmax=max_tip, extent=[bin.left, bin.right, 0, bin_height],
              origin='lower', aspect='auto')
    ax.add_patch(mpatches.Rectangle((bin.left, 0), bin.length, bin_height, fc='none', ec='k', lw=1))

ax.autoscale()
ax.set_ylim(0, 1.05 * ax.get_ylim()[1])
ax.set_xlabel('total bill')
ax.set_ylabel('frequency')
plt.colorbar(ax.images[0], ax=ax, label='tip')
plt.tight_layout()
plt.show()

这是使用带状颜色图 (cmap = plt.get_cmap('Spectral', 9)) 时的样子:

这是另一个使用 'mpg' 数据集的示例,其中包含汽车重量的直方图,并通过每加仑英里数进行着色。

【讨论】:

    【解决方案2】:

    您可以使用 Seaborn 生成热图。 bin / 首先塑造数据框。这是随机数据,所以热图并不那么有趣。

    import seaborn as sns
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    s = 50
    df = pd.DataFrame({"price":np.random.randint(30,120, s),"volume":np.random.randint(1,5, s)})
    
    fig, ax = plt.subplots(2, figsize=[10,6])
    
    df.loc[:,"volume"].plot(ax=ax[0], kind="hist", bins=3)
    # reshape for a heatmap... put price into bins and make 2D
    dfh = df.assign(pbin=pd.qcut(df.price,5)).groupby(["pbin","volume"]).mean().unstack(1).droplevel(0,axis=1)
    axh = sns.heatmap(dfh, ax=ax[1])
    
    

    【讨论】:

      猜你喜欢
      • 2014-12-04
      • 2017-08-28
      • 1970-01-01
      • 2020-05-28
      • 2020-01-12
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多