如何使用seaborn FacetGrid自定义直方图
How to customize histogram using seaborn FacetGrid
我正在使用 seaborn 的 FacetGrid
从参数“xyz”的数据帧 (plot_df
) 中绘制多个直方图。但我也想在这些情节中做以下额外的事情,
- 在 x 值 = 0 处创建垂直轴线
- 用不同的阴影为所有等于或小于 0(在 x 轴上)的 bin 着色
- 仅为那些低于 0(在 x 轴上)的 bin 计算直方图的百分比面积
我可以在线获取很多示例,但使用 seaborn FacetGrid 选项则不行
g = sns.FacetGrid(plot_df, col='xyz', height=5)```
g.map(plt.hist, "slack", bins=50)
您可以遍历生成的轴 (for xyz, ax in g.axes_dict.items(): ....
) 并为每个轴调用绘图函数。
或者,您可以使用自定义函数调用 g.map_dataframe(...)
。该功能将需要绘制到“当前斧头”上。
更改 x 和 y 标签需要在调用 g.map_dataframe()
之后完成,因为 seaborn 会在该函数结束时擦除 x 和 y 标签。
您可以调用plt.setp(g.axes, xlabel='data', ylabel='frequency')
来设置所有子图的标签。或者 g.set_ylabels('...')
只为“外部”子图设置 y 标签。
下面是一些帮助您入门的示例代码:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
def individual_plot(**kwargs):
ax = plt.gca() # get the current ax
data = kwargs['data']['slack'].values
xmin, xmax = data.min(), data.max()
bin_width = xmax / 50
# histogram part > 0
ax.hist(data, bins=np.arange(0.000001, xmax + 0.001, bin_width), color='tomato')
# histogram part < 0
ax.hist(data, bins=-np.arange(0, abs(xmin) + bin_width + 0.001, bin_width)[::-1], color='lime')
# line at x=0
ax.axvline(0, color='navy', ls='--')
# calculate and show part < 0
percent_under_zero = sum(data <= 0) / len(data) * 100
ax.text(0.5, 0.98, f'part < 0: {percent_under_zero:.1f} %',
color='k', ha='center', va='top', transform=ax.transAxes)
# first generate some test data
plot_df = pd.DataFrame({'xyz': np.repeat([*'xyz'], 1000),
'slack': np.random.randn(3000) * 10 + np.random.choice([10, 500], 3000, p=[0.9, 0.1])})
g = sns.FacetGrid(plot_df, col='xyz', height=5)
g.map_dataframe(individual_plot)
plt.setp(g.axes, xlabel='data', ylabel='frequency')
plt.tight_layout()
plt.show()
我正在使用 seaborn 的 FacetGrid
从参数“xyz”的数据帧 (plot_df
) 中绘制多个直方图。但我也想在这些情节中做以下额外的事情,
- 在 x 值 = 0 处创建垂直轴线
- 用不同的阴影为所有等于或小于 0(在 x 轴上)的 bin 着色
- 仅为那些低于 0(在 x 轴上)的 bin 计算直方图的百分比面积
我可以在线获取很多示例,但使用 seaborn FacetGrid 选项则不行
g = sns.FacetGrid(plot_df, col='xyz', height=5)```
g.map(plt.hist, "slack", bins=50)
您可以遍历生成的轴 (for xyz, ax in g.axes_dict.items(): ....
) 并为每个轴调用绘图函数。
或者,您可以使用自定义函数调用 g.map_dataframe(...)
。该功能将需要绘制到“当前斧头”上。
更改 x 和 y 标签需要在调用 g.map_dataframe()
之后完成,因为 seaborn 会在该函数结束时擦除 x 和 y 标签。
您可以调用plt.setp(g.axes, xlabel='data', ylabel='frequency')
来设置所有子图的标签。或者 g.set_ylabels('...')
只为“外部”子图设置 y 标签。
下面是一些帮助您入门的示例代码:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
def individual_plot(**kwargs):
ax = plt.gca() # get the current ax
data = kwargs['data']['slack'].values
xmin, xmax = data.min(), data.max()
bin_width = xmax / 50
# histogram part > 0
ax.hist(data, bins=np.arange(0.000001, xmax + 0.001, bin_width), color='tomato')
# histogram part < 0
ax.hist(data, bins=-np.arange(0, abs(xmin) + bin_width + 0.001, bin_width)[::-1], color='lime')
# line at x=0
ax.axvline(0, color='navy', ls='--')
# calculate and show part < 0
percent_under_zero = sum(data <= 0) / len(data) * 100
ax.text(0.5, 0.98, f'part < 0: {percent_under_zero:.1f} %',
color='k', ha='center', va='top', transform=ax.transAxes)
# first generate some test data
plot_df = pd.DataFrame({'xyz': np.repeat([*'xyz'], 1000),
'slack': np.random.randn(3000) * 10 + np.random.choice([10, 500], 3000, p=[0.9, 0.1])})
g = sns.FacetGrid(plot_df, col='xyz', height=5)
g.map_dataframe(individual_plot)
plt.setp(g.axes, xlabel='data', ylabel='frequency')
plt.tight_layout()
plt.show()