【发布时间】:2025-11-29 04:20:01
【问题描述】:
我似乎无法使用 seaborn FacetGrid 显示二维 histplot 的颜色条。有人可以指出我缺少的链接吗?
了解到已经讨论过类似的解决方案,我无法适应我的用例:
- Has the right position and values for color bar but isn't working for histplot
- This proposal is not running at all & is rather dated so I am not sure it is still supposed to work
- 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 很重要。
编辑:为了清楚起见,从 cmets 看来,问题分为两个步骤:
- 如何标准化所有绘图之间的颜色编码和
- 使用标准化颜色映射在绘图右侧显示一个颜色条
【问题讨论】:
-
您的示例代码可能不代表您的真实数据。您修改范围值(这与您的问题的上下文无关)但在每个类别中具有可比较的(尽管是随机的)分布。如果您修改每个类别出现的概率,您会注意到两件事 - 面板之间的直方图箱的数量会有所不同,并且相同的颜色将代表不同面板中的不同值,从而使组合的颜色条过时。有办法解决这个问题,但你必须完全不同地构建你的程序。
-
如果您将
cbar=True添加到fg.map(),您甚至可能会看到颜色代码与您的版本不同。 -
谢谢。是的,
cbarfor 每个子图确实有效,但它占用了大量空间,因此我的目标是将栏放在右边距。解决颜色编码问题是我提出问题的动机的一部分。 -
那么,您真正的问题不是关于如何创建颜色条,而是如何规范化直方图,以便一种颜色在所有面板中表示相同的值?
-
嗯,是的,实际上两者都归一化 histplots 颜色编码并在右侧显示归一化的颜色条。为了更清晰,我将进行编辑。
标签: python matplotlib seaborn