怎么用Python绘制帕累托图

发布时间:2021-11-25 11:24:10 作者:iii
来源:亿速云 阅读:461
# 怎么用Python绘制帕累托图

## 1. 帕累托图简介

帕累托图(Pareto Chart)是一种特殊的柱状图,它将数据按照频率或影响程度从高到低排列,并叠加累积百分比曲线。这种图表源自帕累托原则(80/20法则),即80%的结果往往由20%的原因造成。

### 1.1 帕累托图的核心组成
- **降序排列的柱状图**:显示各类别的绝对数量
- **累积百分比折线图**:显示累计占比
- **80%参考线**:帮助识别关键因素

### 1.2 典型应用场景
- 质量缺陷分析
- 客户投诉分类
- 库存管理(ABC分析)
- 业务流程优化

## 2. 准备工作

### 2.1 所需Python库
```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter

2.2 示例数据集

我们使用一个模拟的客户投诉数据:

data = {
    '投诉类型': ['送货延迟', '产品质量', '包装破损', '客服态度', '错误商品', '网站故障'],
    '投诉次数': [45, 32, 18, 12, 8, 5]
}
df = pd.DataFrame(data)

3. 基础帕累托图实现

3.1 数据处理

# 按投诉次数降序排列
df = df.sort_values(by='投诉次数', ascending=False)

# 计算累积百分比
df['累积百分比'] = df['投诉次数'].cumsum() / df['投诉次数'].sum() * 100

3.2 绘制双轴图表

fig, ax1 = plt.subplots(figsize=(10, 6))

# 柱状图(左轴)
ax1.bar(df['投诉类型'], df['投诉次数'], color='C0')
ax1.set_xlabel('投诉类型')
ax1.set_ylabel('投诉次数', color='C0')
ax1.tick_params(axis='y', labelcolor='C0')

# 折线图(右轴)
ax2 = ax1.twinx()
ax2.plot(df['投诉类型'], df['累积百分比'], color='C1', marker='o')
ax2.set_ylabel('累积百分比', color='C1')
ax2.tick_params(axis='y', labelcolor='C1')
ax2.yaxis.set_major_formatter(PercentFormatter())

# 添加80%参考线
ax2.axhline(80, color='red', linestyle='--')

plt.title('客户投诉帕累托分析')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

4. 高级定制技巧

4.1 样式美化

plt.style.use('seaborn')

fig, ax1 = plt.subplots(figsize=(12, 7))

# 自定义柱状图颜色
colors = plt.cm.viridis(np.linspace(0.8, 0.2, len(df)))
bars = ax1.bar(df['投诉类型'], df['投诉次数'], color=colors)

# 添加数据标签
for bar in bars:
    height = bar.get_height()
    ax1.text(bar.get_x() + bar.get_width()/2., height,
             f'{height}',
             ha='center', va='bottom')

# 折线图增强
ax2 = ax1.twinx()
line, = ax2.plot(df['投诉类型'], df['累积百分比'], 
                color='red', marker='D', 
                linewidth=2, markersize=8)

# 添加折线图数据点标签
for x, y in zip(df['投诉类型'], df['累积百分比']):
    ax2.text(x, y, f'{y:.1f}%', 
            color='red', ha='left', va='bottom')

# 参考线增强
ax2.axhline(80, color='darkred', linestyle=':', linewidth=1.5)
ax2.text(0.5, 82, '80% 关键线', color='darkred')

plt.title('客户投诉帕累托分析\n(2023年度数据)', pad=20)
ax1.set_xlabel('投诉类型', labelpad=10)
ax1.set_ylabel('投诉次数', labelpad=10)
ax2.set_ylabel('累积百分比', labelpad=10)
plt.xticks(rotation=30, ha='right')
plt.tight_layout()

4.2 交互式版本

使用Plotly创建交互式帕累托图:

import plotly.graph_objects as go
from plotly.subplots import make_subplots

fig = make_subplots(specs=[[{"secondary_y": True}]])

# 添加柱状图
fig.add_trace(
    go.Bar(
        x=df['投诉类型'],
        y=df['投诉次数'],
        name="投诉次数",
        marker_color=px.colors.qualitative.Pastel
    ),
    secondary_y=False,
)

# 添加折线图
fig.add_trace(
    go.Scatter(
        x=df['投诉类型'],
        y=df['累积百分比'],
        name="累积百分比",
        mode='lines+markers',
        line=dict(color='firebrick', width=2)
    ),
    secondary_y=True,
)

# 添加参考线
fig.add_hline(
    y=80, 
    line_dash="dot",
    line_color="red",
    annotation_text="80% 分界线",
    annotation_position="bottom right"
)

# 布局设置
fig.update_layout(
    title_text="交互式帕累托分析",
    hovermode="x unified",
    template="plotly_white"
)
fig.update_yaxes(
    title_text="<b>投诉次数</b>",
    secondary_y=False
)
fig.update_yaxes(
    title_text="<b>累积百分比</b>",
    secondary_y=True,
    ticksuffix="%"
)

fig.show()

5. 实际案例应用

5.1 制造业缺陷分析

# 模拟数据
defects = {
    '缺陷类型': ['划痕', '尺寸偏差', '颜色差异', '材料缺陷', '装配问题'],
    '数量': [120, 85, 62, 45, 30]
}
df_defects = pd.DataFrame(defects)

5.2 零售业库存ABC分析

# 计算库存价值
inventory = pd.read_csv('inventory_data.csv')
inventory['价值'] = inventory['单价'] * inventory['库存量']
inventory = inventory.sort_values('价值', ascending=False)
inventory['累积百分比'] = inventory['价值'].cumsum() / inventory['价值'].sum() * 100

6. 常见问题解决

6.1 类别过多处理

当类别超过15个时:

# 合并小类别为"其他"
threshold = df['投诉次数'].sum() * 0.03  # 3%阈值
small_cats = df[df['投诉次数'] < threshold]
if not small_cats.empty:
    other_row = pd.DataFrame({
        '投诉类型': ['其他'],
        '投诉次数': [small_cats['投诉次数'].sum()]
    })
    df = pd.concat([df[df['投诉次数'] >= threshold], other_row])

6.2 数据更新自动化

def generate_pareto(data, title, xcol, ycol):
    """自动化帕累托图生成函数"""
    df = data.sort_values(ycol, ascending=False)
    df['累积百分比'] = df[ycol].cumsum() / df[ycol].sum() * 100
    
    fig, ax1 = plt.subplots(figsize=(10, 6))
    ax1.bar(df[xcol], df[ycol])
    ax1.set_ylabel(ycol)
    
    ax2 = ax1.twinx()
    ax2.plot(df[xcol], df['累积百分比'], color='r', marker='o')
    ax2.set_ylabel('累积百分比 (%)')
    ax2.yaxis.set_major_formatter(PercentFormatter())
    ax2.axhline(80, color='k', linestyle='--')
    
    plt.title(title)
    plt.xticks(rotation=45)
    return fig

7. 最佳实践建议

  1. 数据排序:确保始终按数值降序排列
  2. 双轴刻度:保持左右轴比例协调
  3. 颜色对比:使用对比色区分柱状图和折线图
  4. 移动端适配:调整字体大小和图表尺寸
  5. 动态更新:考虑使用Jupyter Notebook实现动态更新

8. 扩展应用

8.1 时间序列帕累托

# 按月份分析趋势
monthly_data = df.groupby(['月份', '投诉类型']).sum().unstack()

8.2 多维度分析

# 使用seaborn分面
import seaborn as sns
g = sns.FacetGrid(data=df, col='地区', col_wrap=3)
g.map_dataframe(generate_pareto, ...)

9. 总结

Python绘制帕累托图的关键步骤: 1. 数据准备和排序 2. 计算累积百分比 3. 创建双轴图表 4. 添加格式化和标注 5. 进行交互式增强(可选)

通过Matplotlib的基础实现和Plotly的交互式扩展,我们可以创建适用于不同场景的帕累托分析图表,帮助识别关键影响因素,支持数据驱动的决策过程。


附录:完整代码示例

# 完整示例代码
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter

def create_pareto(data, value_col, category_col, title=""):
    """创建帕累托图的完整函数"""
    # 数据处理
    df = data.sort_values(value_col, ascending=False).copy()
    df['cum_pct'] = df[value_col].cumsum() / df[value_col].sum() * 100
    
    # 创建图表
    fig, ax1 = plt.subplots(figsize=(12, 6))
    
    # 柱状图
    bars = ax1.bar(df[category_col], df[value_col], color='steelblue')
    ax1.set_ylabel("频次", color='steelblue')
    ax1.tick_params(axis='y', labelcolor='steelblue')
    
    # 折线图
    ax2 = ax1.twinx()
    ax2.plot(df[category_col], df['cum_pct'], 
            color='tomato', marker='o')
    ax2.set_ylabel("累积百分比", color='tomato')
    ax2.tick_params(axis='y', labelcolor='tomato')
    ax2.yaxis.set_major_formatter(PercentFormatter())
    
    # 80%参考线
    ax2.axhline(80, color='red', linestyle='--', alpha=0.5)
    
    # 格式设置
    plt.title(f"帕累托图: {title}")
    plt.xticks(rotation=45, ha='right')
    plt.tight_layout()
    
    return fig

# 使用示例
data = pd.DataFrame({
    '问题': ['A', 'B', 'C', 'D', 'E'],
    '次数': [50, 30, 15, 10, 5]
})
fig = create_pareto(data, '次数', '问题', "质量问题分析")
plt.show()

”`

推荐阅读:
  1. 如何使用Python绘制漫步图
  2. python如何绘制彩虹图

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:Python怎么给dataframe循环命名

下一篇:Linux系统安装与基本使用的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》