海纳风格网格用于分层计数图?

2024-05-19 16:35:35 发布

您现在位置:Python中文网/ 问答频道 /正文

注意:GitHub上可以找到full reproduction notebook for this question

我有一个数据集,其中包含我想按类分组的HTTP响应代码的分布。示例数据可以这样生成:

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

%matplotlib inline

mock_http_response_data = pd.DataFrame({
    'response_code':np.repeat([200, 201, 202, 204, 302, 304, 400, 404, 500, 502], 250 ),
})

我已经在数据中添加了一个基于“响应状态”的列,称为“响应类”。响应类包含与特定响应的类相对应的标签:

  • 2xx:成功
  • 3xx:警告
  • 4xx:客户端错误
  • 4xx:服务器错误

确定响应类的函数是:

^{pr2}$

列的添加方式如下:

# Add 'Response class' column to API Logs, where response class is determined by HTTP status code
mock_http_response_data['response_class'] = mock_http_response_data.apply(determine_response_class, axis='columns')

“响应状态”(HTTP状态代码)数据用基本计数图正确绘制:

sns.countplot(
    x='_source.response_status',
    data=results_df,
    color='teal',
    saturation=0.7)

uniform status code distribution

当我尝试创建一个countplots的FacetGrid时,图表似乎可以工作,但是标签不正确:

grid = sns.FacetGrid(mock_http_response_data, col='response_class')

grid.map(sns.countplot, 'response_code')

enter image description here

我预计countplots的FaceGrid将具有以下x轴标签:

  • 200个
  • 201年
  • 202号
  • 302个
  • 304
  • 400个
  • 404号
  • 500个
  • 502个

如何创建countplots的FacetGrid,以便标签正确,并且分面数据从高到低排序(例如,“success”类列)?在


Tags: 数据importhttpdataresponse状态ascode
1条回答
网友
1楼 · 发布于 2024-05-19 16:35:35

出现错误标签的问题是因为默认情况下,子图的x轴是共享的,因此所有绘图都将具有与最后一个绘图相同的x轴。在

您可以使用sharex=False参数来防止共享轴:

grid = sns.FacetGrid(df, col='class', sharex=False)

enter image description here

和13;

和13;

分类的问题现在是鸡还是蛋的问题。为了设置列的顺序,您需要知道每个列的计数,这些计数是作为打印的一部分确定的。在这一点上,保持数据生成、分析和可视化之间的明确分离可能是明智的。下面将显示一个排序图,不使用FacetGrid,它首先对数据帧中的值进行排序。在

import pandas as pd
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
import seaborn as sns

codes = [200, 201, 202, 204, 302, 304, 400, 404, 500, 502]
p = np.random.rand(len(codes))
p = p/p.sum()
df = pd.DataFrame({ 'code': np.random.choice(codes, size=300, p=p) })

def determine_response_class(row):    
    response_code = row['code']

    if response_code >= 200 and response_code < 300:
        return 'success'
    elif response_code >= 300 and response_code < 400:
        return 'warning'
    elif response_code >= 400 and response_code < 500:
        return 'client_error'
    elif response_code >= 500 and response_code < 600:
        return 'server_error'
    else:
        return 'unknown'

df['class'] = df.apply(determine_response_class, axis='columns')

df2 = df.groupby(["code","class"]).size().reset_index(name="count") \
        .sort_values(by="count", ascending=0).reset_index(drop=True)

fig, axes = plt.subplots(ncols=4, sharey=True, figsize=(8,3))
for ax,(n, group) in zip(axes, df2.groupby("class")):
    sns.barplot(x="code",y="count", data=group, ax=ax, color="C0", order=group["code"])
    ax.set_title(n)

plt.tight_layout()
plt.show()

enter image description here

相关问题 更多 >