Seaborn线图提前应用对数轴缩放时,负误差边界的转换机制及表现差异问题
Seaborn线图提前应用对数轴缩放时,负误差边界的转换机制及表现差异问题
我正在用Seaborn绘制一些折线图:
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd # dfs: dict[str, DataFrame] fig, ax = plt.subplots() for label, df in dfs.items(): sns.lineplot( data=df, x="Iteration", y="Loss", errorbar="sd", label=label, ax=ax, ) ax.set(xscale='log', yscale='log')
绘制结果里,"effector_final_velocity"曲线的下方误差带出现了被截断的负值——因为在某些迭代步骤中,损失的标准差大于均值。
但如果我把ax.set(xscale='log', yscale='log')放在循环调用sns.lineplot之前,绘制结果就会出现未被截断的负值误差带。
我完全搞不懂这种未截断的情况是怎么出现的。
我去查看了seaborn.relational的源码:lineplot方法最后会调用_LinePlotter实例的plot方法,这个方法是通过把预先计算好的标准差边界传给ax.fill_between来绘制误差带的。
在这些边界值被传给ax.fill_between之前,我特意检查过它们的值,那些本应被截断的负值依然存在。所以我原本以为这种“不截断”的行为是matplotlib在ax.fill_between调用过程中产生的,因为_LinePlotter.plot在返回前似乎没有对数据做其他相关的转换,而且lineplot方法会直接返回。
不过我又做了一个简单的测试,直接用matplotlib调用fill_between传入包含负值的下限:
import numpy as np fig, ax = plt.subplots(1, 1, figsize=(5, 5)) np.random.seed(5678) ax.fill_between( np.arange(10), np.random.random((10,)) - 0.2, np.random.random((10,)) + 0.75, ) ax.set_yscale('log')
这个例子里,不管是先调用ax.set_yscale('log')还是后调用,结果都是一样的——负值误差带都会被截断。
我花了好一阵在Seaborn和matplotlib的文档里找相关解释,也在Stack Exchange等平台搜过答案,但一直没搞清楚这到底是怎么回事。
备注:内容来源于stack exchange,提问作者mll
相关产品推荐
相关产品推荐

