如何在Seaborn FacetGrid热图中用EngFormatter自定义标注
解决Seaborn分面热图标注的EngFormatter格式化问题
问题原因
你之前尝试用fg.texts获取标注文本,但FacetGrid.texts存储的是分面标题、坐标轴标签等全局文本,不是热图内部的标注文本。热图的标注是每个子图(Axes)的独立元素,需要从每个子图的ax.texts中获取。
解决代码
以下是修改后的完整代码,包含数据处理、绘图和标注格式化:
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd from matplotlib.ticker import EngFormatter # 加载样本数据集 df = pd.DataFrame({ 'index': [0,1,2,3,4], 'time_interval': ['time_2','time_1','time_1','time_2','time_1'], 'user_action': ['','Click Use','Click View Detail','Click View Detail','Click See All'], 'segment': ['Super Heavy','Medium','Light','Medium','Medium'], 'users': [1233,10000,2000000,3999,14542] }) 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 ) # 创建EngFormatter实例,指定小数位数 formatter = EngFormatter(places=1) # 遍历每个分面子图处理标注 for ax in fg.axes.flat: for text in ax.texts: try: # 将文本转为数值后格式化 val = float(text.get_text()) text.set_text(formatter.format_data(val)) except ValueError: # 跳过空值或非数值单元格 continue plt.tight_layout() plt.show()
关键说明
- 定位标注元素:通过
fg.axes.flat遍历所有分面子图,再用ax.texts获取当前子图内的热图标注文本。 - EngFormatter配置:
EngFormatter(places=1)控制标注的小数位数,format_data()方法自动将数值转换为带工程单位的字符串(如1233→1.2k、2000000→2.0M)。 - 异常处理:针对空单元格或非数值文本,捕获
ValueError避免程序报错。
内容的提问来源于stack exchange,提问作者Brian Tran
相关产品推荐
相关产品推荐

