matplotlib 将Seaborn FacetGrid中热图的文本注解自定义为EngFormatter样式

tag5nh1u  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(125)

当我试图生成一个热图来比较不同用户段在不同时间段的表现时,我无法以EngFormatter风格自定义热图的注解(即1233 = 1k,10000 = 10k,2000000 = 2M等)。我无法找到FacetGrid中每个热图下的注解文本元素的位置。
如何自定义Facegrid Annotation的单位?
我的努力:

import matplotlib.pyplot as plt
import seaborn as sns

def draw_heatmap(*args, **kwargs):
    data = kwargs.pop('data')
    d = data.pivot(index=args[1], columns=args[0], values=args[2])
    sns.heatmap(d, **kwargs)

fg = sns.FacetGrid(df, col='time_interval',height=6)
fg.map_dataframe(
    draw_heatmap,
    'user_action', 'segment', 'users',
    cbar=True, cmap="Blues", square = True, annot=True,fmt='.2g'
)

from matplotlib.ticker import EngFormatter
for t in fg.texts: t.set_text(EngFormatter(t.get_text()))

电流输出:

所需输出:
与上述类似的可视化,但其中显示的热图文本注解为EngFormatter样式
样本数据集:

index,time_interval,user_action,segment,users
0,time_2,,Super Heavy,1233
1,time_1,Click Use,Medium,10000
2,time_1,Click View Detail,Light,2000000
3,time_2,Click View Detail,Medium,3999
4,time_1,Click See All,Medium,14542

会话信息:

polars==0.17.3
pandas==1.5.3
seaborn==0.12.2
bqjvbblv

bqjvbblv1#

您已经非常接近正确了,但是将Axes对象的texts属性的迭代和EngFormatter更改 * 放在draw_heatmap函数中。您还需要捕获seaborn热图图本身的Axes以修改其注解(即,不是FacetGrid的texts属性,而是网格中热图的texts属性)。
例如,使用您提供的示例数据(为扩展演示而略有修改):

import itertools as itl
import random

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

from matplotlib.ticker import EngFormatter

times = ["time_1", "time_2"]
user_actions = ["Click See All", "Click Use", "Click View Detail"]
segments = ["Light", "Medium", "Heavy"]

all_combos = list(map(list, list(itl.product(times, user_actions, segments))))

cols = ["time_interval", "user_action", "segment", "users"]

data = [c + [random.randint(1, int(2e6))] for c in all_combos]

df = pd.DataFrame(data, columns=cols)

def draw_heatmap(*args, **kwargs):
    data = kwargs.pop("data")
    d = data.pivot(index=args[1], columns=args[0], values=args[2])
    ax = sns.heatmap(d, **kwargs)

    # Make annotations of heatmaps in EngFormatter style
    for text in ax.texts:
        text.set_text(
            EngFormatter()(float(text.get_text()))
        )

fg = sns.FacetGrid(df, col="time_interval", height=6)
fg.map_dataframe(
    draw_heatmap,
    "user_action",
    "segment",
    "users",
    cbar=True,
    cmap="Blues",
    square=True,
    annot=True,
    fmt=".2g",
)

plt.show()

生产:

其中,上述随机生成的数据(“df”)为:

time_interval        user_action segment    users
0         time_1      Click See All   Light   744670
1         time_1      Click See All  Medium   150098
2         time_1      Click See All   Heavy   588170
3         time_1          Click Use   Light  1811019
4         time_1          Click Use  Medium   495390
5         time_1          Click Use   Heavy  1312397
6         time_1  Click View Detail   Light  1598512
7         time_1  Click View Detail  Medium  1763711
8         time_1  Click View Detail   Heavy   930745
9         time_2      Click See All   Light  1832730
10        time_2      Click See All  Medium  1868217
11        time_2      Click See All   Heavy     4131
12        time_2          Click Use   Light  1163743
13        time_2          Click Use  Medium   600851
14        time_2          Click Use   Heavy  1019326
15        time_2  Click View Detail   Light  1527671
16        time_2  Click View Detail  Medium   559187
17        time_2  Click View Detail   Heavy  1943017

相关问题