numpy 如何绘制两个直方图之间的差异

omtl5h9j  于 2023-05-22  发布在  其他
关注(0)|答案(2)|浏览(136)

我正在绘制两个分布作为histplots,并希望可视化它们之间的差异。分布非常相似:

我用来生成其中一个图的代码如下所示:

sns.histplot(
    data=dfs_downvoted_percentages["only_pro"],
    ax=axes[0],
    x="percentage_downvoted",
    bins=30,
    stat="percent",
)

我的主管建议绘制归一化分布之间的差异,基本上显示一个图从另一个图中减去。最终结果应该是一个图,其中一些箱低于0(如果图2中的箱大于图1中的箱)。因此,图之间的相似性被擦除,差异被突出显示。
1.这有道理吗?这些情节是一篇有望发表的论文的一部分;我以前没有见过这样的情节,但正如他解释的那样,这对我来说是有意义的。有没有更好的方法来形象化我想表达的东西?我已经有了另一个图,在那里我过滤掉了所有x=0的值,这样其他的值就变得更明显了。
1.有没有一个简单的方法来实现这一利用海运?
如果没有:我知道如何规范化数据并手工计算每个bin的百分比。但我找不到的是一种由箱子组成的图,它提供了有负箱子的可能性。我知道如何创建一个30个数据点的线图来显示计算出的差异,但我宁愿让它在视觉上类似于原始图,用bin而不是一条线。我能用什么样的情节来实现呢?

imzjd6km

imzjd6km1#

  • 使用np.histogram,它返回histbin_edges
  • 两个函数调用必须使用相同的bin_edges
  • 减去每个 Dataframe 的hist,并将其与bin_edges进行绘图。
  • h_diff绘制为条形图。
  • bin_edge比条形多一个,因此选择除了最后一个值bin_edges[:-1]之外的所有值作为传递给x=的x轴标签。
  • sns.barplot的x-tick是0索引的,因此用一个额外的tick重置tick,将它们偏移-0.5,然后用所有的bin_edges重新标记tick。
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# sample data
np.random.seed(2023)
a = np.random.normal(50, 15, (100,))
b = np.random.normal(30, 8, (100,))

# dataframe from sample distributions
df = pd.DataFrame({'a': a, 'b': b})

# calculate the histogram for each distribution
bin_edges = np.arange(10, 91, 10)

a_hist, _ = np.histogram(df.a, bins=bin_edges) 
b_hist, _ = np.histogram(df.b, bins=bin_edges) 

# calculate the difference
h_diff = a_hist - b_hist

# plot
fig, ax = plt.subplots(figsize=(7, 5))
sns.barplot(x=bin_edges[:-1], y=h_diff, color='tab:blue', ec='k', width=1, alpha=0.8, ax=ax)
ax.set_xticks(ticks=np.arange(0, 9)-0.5, labels=bin_edges)
ax.margins(x=0.1)
_ = ax.set(title='Difference between Sample A and B: hist(a) - hist(b)', ylabel='Difference', xlabel='Bin Ranges')

  • 另一种选择是绘制直方图和隐藏条,我认为这是一种更好的数据呈现方式,可以显示两个数据集的分布。
fig, ax = plt.subplots(figsize=(7, 5))
sns.histplot(data=df, multiple='dodge', common_bins=True, ax=ax, bins=bin_edges)

byqmnocz

byqmnocz2#

我认为你可以从彼此中减去2个dfs来做另一个直方图,或者你可以用不同的颜色代码将它们绘制在彼此的顶部,这样你就可以可视化差异。
举个例子:

import seaborn as sns
import matplotlib.pyplot as plt

data1 = [1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5]
data2 = [2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6]

sns.histplot(data=data1, label='Data 1', color='red', alpha=0.5)
sns.histplot(data=data2, label='Data 2', color='blue', alpha=0.5)

plt.xlabel('Value')
plt.ylabel('Count')
plt.legend()

plt.show()

相关问题