如何在 y=1 处开始 Seaborn 对数条形图
How to start Seaborn Logarithmic Barplot at y=1
我在弄清楚如何让 Seaborn 在对数条形图中显示正确的值时遇到问题。在理想情况下,我的值应该是 1。我的数据系列 (5,2,1,0.5,0.2) 有一组偏离统一的值,我想在对数条形图中显示这些值。但是,在标准对数条形图中绘制时,它显示以下内容:
但是 1 以下的值显示为从 -infinity 增加到它们的值,而实际值应该如下所示:
奇怪的是,我找不到 Seaborn、Pandas 或 Matplotlib 属性来“捕捉”到不同的水平轴或“对齐”或 ymin/ymax。我有一种无法找到它的感觉,因为我无法找到推倒我最喜欢的搜索引擎的条款。我发现的一些半解决方案 just 与我正在寻找的不匹配,或者没有 xaxis = 1 或 ylog。尝试使用一些 jank Matplotlib 行:
如果有人知道正确的条款或解决方案,请提前致谢。
这是我使用的 Jupyter 细胞:
{1}
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
data = {'X': ['A','B','C','D','E'], 'Y': [5,2,1,0.5,0.2]}
df = pd.DataFrame(data)
{2}
%matplotlib widget
g = sns.catplot(data=df, kind="bar", y = "Y", x = "X", log = True)
{3}
%matplotlib widget
plt.vlines(x=data['X'], ymin=1, ymax=data['Y'])
您可以让条形从 1 而不是 0 开始。您需要直接使用 sns.barplot
。
示例代码减去所有 y 值的 1,并将条 bottom
设置为 1
。
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import seaborn as sns
import pandas as pd
import numpy as np
data = {'X': ['A', 'B', 'C', 'D', 'E'], 'Y': [5, 2, 1, 0.5, 0.2]}
df = pd.DataFrame(data)
ax = sns.barplot(y=df["Y"] - 1, x=df["X"], bottom=1, log=True, palette='flare_r')
ax.axhline(y=1, c='k')
# change the y-ticks, as the default shows too few in this case
ax.set_yticks(np.append(np.arange(.2, .8, .1), np.arange(1, 7, 1)), minor=False)
ax.set_yticks(np.arange(.3, 6, .1), minor=True)
ax.yaxis.set_major_formatter(lambda x, pos: f'{x:.0f}' if x >= 1 else f'{x:.1f}')
ax.yaxis.set_minor_formatter(NullFormatter())
ax.bar_label(ax.containers[0], labels=df["Y"])
sns.despine()
plt.show()
PS:使用这些特定值,绘图可能没有对数刻度:
我在弄清楚如何让 Seaborn 在对数条形图中显示正确的值时遇到问题。在理想情况下,我的值应该是 1。我的数据系列 (5,2,1,0.5,0.2) 有一组偏离统一的值,我想在对数条形图中显示这些值。但是,在标准对数条形图中绘制时,它显示以下内容:
但是 1 以下的值显示为从 -infinity 增加到它们的值,而实际值应该如下所示:
奇怪的是,我找不到 Seaborn、Pandas 或 Matplotlib 属性来“捕捉”到不同的水平轴或“对齐”或 ymin/ymax。我有一种无法找到它的感觉,因为我无法找到推倒我最喜欢的搜索引擎的条款。我发现的一些半解决方案 just 与我正在寻找的不匹配,或者没有 xaxis = 1 或 ylog。尝试使用一些 jank Matplotlib 行:
如果有人知道正确的条款或解决方案,请提前致谢。
这是我使用的 Jupyter 细胞:
{1}
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
data = {'X': ['A','B','C','D','E'], 'Y': [5,2,1,0.5,0.2]}
df = pd.DataFrame(data)
{2}
%matplotlib widget
g = sns.catplot(data=df, kind="bar", y = "Y", x = "X", log = True)
{3}
%matplotlib widget
plt.vlines(x=data['X'], ymin=1, ymax=data['Y'])
您可以让条形从 1 而不是 0 开始。您需要直接使用 sns.barplot
。
示例代码减去所有 y 值的 1,并将条 bottom
设置为 1
。
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import seaborn as sns
import pandas as pd
import numpy as np
data = {'X': ['A', 'B', 'C', 'D', 'E'], 'Y': [5, 2, 1, 0.5, 0.2]}
df = pd.DataFrame(data)
ax = sns.barplot(y=df["Y"] - 1, x=df["X"], bottom=1, log=True, palette='flare_r')
ax.axhline(y=1, c='k')
# change the y-ticks, as the default shows too few in this case
ax.set_yticks(np.append(np.arange(.2, .8, .1), np.arange(1, 7, 1)), minor=False)
ax.set_yticks(np.arange(.3, 6, .1), minor=True)
ax.yaxis.set_major_formatter(lambda x, pos: f'{x:.0f}' if x >= 1 else f'{x:.1f}')
ax.yaxis.set_minor_formatter(NullFormatter())
ax.bar_label(ax.containers[0], labels=df["Y"])
sns.despine()
plt.show()
PS:使用这些特定值,绘图可能没有对数刻度: