gpt4 book ai didi

python - FacetGrid 上的 Seaborn 颜色条用于具有标准化颜色映射的 histplot

转载 作者:行者123 更新时间:2023-12-05 06:00:21 24 4
gpt4 key购买 nike

我似乎无法使用 seaborn FacetGrid 显示二维 histplot 的颜色条。有人可以指点我丢失的链接吗?

了解已经讨论过类似的解决方案,但我无法适应我的用例:

  1. Has the right position and values for color bar but isn't working for histplot
  2. This proposal is not running at all & is rather dated so I am not sure it is still supposed to work
  3. Seems to have fixed vmin/vmax and does not work with histplot

具体来说,我希望扩展下面的代码以便显示颜色条。

import pandas as pd
import numpy as np
import seaborn as sns

df = pd.DataFrame(list(zip([random.randint(0,10) for i in range(1000)], pd.to_datetime(
[d.strftime('%Y-%m-%d') for d in pd.date_range('1800-01-01', periods=250, freq='1d')]+\
[d.strftime('%Y-%m-%d') for d in pd.date_range('1800-01-01', periods=250, freq='1d')]+\
[d.strftime('%Y-%m-%d') for d in pd.date_range('1800-01-01', periods=250, freq='1d')]+\
[d.strftime('%Y-%m-%d') for d in pd.date_range('1800-01-01', periods=250, freq='1d')]),
[random.choice(string.ascii_letters[26:30]) for i in range(1000)])),
columns=["range","date","case_type"])
df["range"][df["case_type"]=="A"] = [random.randint(4562,873645) for i in range(1000)]
df["range"][df["case_type"]=="C"] = [random.random() for i in range(1000)]
fg = sns.FacetGrid(df, col="case_type", col_wrap=2, sharey=False)

fg.map(sns.histplot, "date", "range", stat="count", data=df)
fg.set_xticklabels(rotation=30)
fg.fig.show()

目标是在分面网格的右侧有一个颜色条,横跨整个图表 - 这里有两行,但可能会显示更多。显示的 2D 直方图具有一些非常不同的数据类型,因此每个 bin 和颜色的计数可能非常不同,了解“深蓝色”是 100 还是 1000 很重要。

2dhistogram in search of a colorbar

编辑:为了清楚起见,从评论中可以看出问题分为两个步骤:

  1. 如何标准化所有地 block 之间的颜色编码和
  2. 使用标准化颜色映射在图的右侧显示颜色条

最佳答案

我不确定是否有一种 seaborn 固有的方法来实现您想要的情节。但是我们可以预先计算 bin numbervmin/vmax 的合理值,并将它们应用于所有 histplots:

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

#generate a test dataset with different case_type probabilities
np.random.seed(123)
p1, p2, p3 = 0.8, 0.1, 0.03
df = pd.DataFrame(list(zip(np.random.randint(0, 20, 1000),
pd.to_datetime(4 * [d.strftime('%Y-%m-%d') for d in pd.date_range('1800-01-01', periods=250, freq='1d')]),
np.random.choice(list("ABCD"),size=1000, p=[p1, p2, p3, 1-(p1+p2+p3)]))),
columns=["range","date","case_type"])
df.loc[df.case_type == "A", "range"] *= 3
df.loc[df.case_type == "B", "range"] *= 23
df.loc[df.case_type == "C", "range"] *= 123

#determine the bin number for the x-axis
_, bin_edges = np.histogram(df["date"].dt.strftime("%Y%m%d").astype(int), bins="auto")
bin_nr = len(bin_edges)-1

#predetermine min and max count for each category
c_types = df["case_type"].unique()
vmin_list, vmax_list = [], []
for c_type in c_types:
arr, _, _ = np.histogram2d(df.loc[df.case_type == c_type, "date"], df.loc[df.case_type == c_type, "range"], bins=bin_nr)
vmin_list.append(arr.min())
vmax_list.append(arr.max())

#find lowest and highest counts for all subplots
vmin_all = min(vmin_list)
vmax_all = max(vmax_list)

#now we are ready to plot
fg = sns.FacetGrid(df, col="case_type", col_wrap=2, sharey=False)
#create common colorbar axis
cax = fg.fig.add_axes([.92, .12, .02, .8])
#map colorbar to colorbar axis with common vmin/vmax values
fg.map(sns.histplot,"date", "range", stat="count", bins=bin_nr, vmin=vmin_all, vmax=vmax_all, cbar=True, cbar_ax=cax, data=df)
#prevent overlap
fg.fig.subplots_adjust(right=.9)
fg.set_xticklabels(rotation=30)

plt.show()

示例输出: enter image description here

您可能还注意到我更改了您的示例数据框,以便 case_types 以不同的频率出现,否则您看不到 histplots 之间的太大差异。您还应注意,histplots 是按照它们在数据框中出现的顺序绘制的,这可能不是您希望在图表中看到的顺序。

免责声明:这主要基于 mwaskom's answer .

关于python - FacetGrid 上的 Seaborn 颜色条用于具有标准化颜色映射的 histplot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67701339/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com