Python管理咨询数据可视化实战:收入分布与顾问利用率双轴对比图表生成脚本

管理咨询项目分析的可视化图表生成脚本,主要用于展示不同项目类型的收入分布、顾问利用率对比


1. 核心功能概述

  • 数据模拟:生成4类管理咨询项目(战略咨询、运营优化、数字化转型、人力资源咨询)的模拟
  • 数据可视化
    • 直方图:展示特定
    • 分组柱状图:比较不同项目类型的平均收入与顾问利用率。
    • 标注与样式:添加目标收入线、高利润区域标记、利润率标签、数据说明、版权信息等。

2. 代码模块详解

(1) 字体设置
复制代码

Python
1def set_chinese_font(): 2 """尝试设置中文字体,回退到通用方案""" 3 try: 4 # 尝试使用中文系统字体(如SimHei、Microsoft YaHei等) 5 chinese_fonts = ['SimHei', 'Microsoft YaHei', 'KaiTi', 'STXihei', 'STHeiti'] 6 forfontinchinese_fonts:7 iffontinfont_manager.findfont(font):8 plt.rcParams['font.sans-serif'] = [font] 9 plt.rcParams['axes.unicode_minus'] = False 10 return 11 # 回退方案 12 plt.rcParams['font.sans-serif'] = ['sans-serif'] 13 except: 14 plt.rcParams['font.sans-serif'] = ['sans-serif']

  • 作用:确保图表能正确显示中文标签(如项目名称、坐标轴标题等),避免乱码。
  • 技术点 :使用matplotlib.font_manager动态查找系统中可用的中文字体。

(2) 数据生成
复制代码

Python
1def generate_project_data(name, revenue_base, utilization_rate, margin): 2 """生成咨询项目数据""" 3 revenue_data = np.random.normal(loc=revenue_base, scale=revenue_base*0.2, size=50) 4 utilization_data = np.random.normal(loc=utilization_rate, scale=0.1, size=50) 5 return{6 'name': name, 7 'revenue': revenue_data, 8 'utilization': utilization_data, 9 'margin': margin, 10 'color': '' 11 }

  • 作用 :生成模拟数据,使用numpy.random.normal生成正态分布的收入和利用率数据。
  • 参数
    • revenue_base:收入均值。
    • utilization_rate:顾问利用率均值。
    • margin:利润率。

(3) 图表绘制
  • 直方图(第一子图)

    • 展示"战略咨询"项目的收入分布。
    • 用不同颜色和透明度对比"数字化转型"项目。
    • 标注目标收入线(600万元)和高利润区域(400-700万元)。
  • 分组柱状图(第二子图)

    • 横轴:项目类型(战略咨询、运营优化等)。

    • 纵轴:左轴为平均收入(万元),右轴为顾问利用率(%)。

    • 双柱状图对比:同一项目类型的收入与利用率。

    • 添加利润率标签(如"利润率: 45%")。

      import matplotlib.pyplot as plt
      import numpy as np
      import pandas as pd
      from matplotlib import font_manager
      from datetime import datetime

      更健壮的字体设置方案

      def set_chinese_font():
      """尝试设置中文字体,回退到通用方案"""
      try:
      # 尝试查找系统中可用的中文字体
      chinese_fonts = ['SimHei', 'Microsoft YaHei', 'KaiTi', 'STXihei', 'STHeiti']
      for font in chinese_fonts:
      if font in font_manager.findfont(font):
      plt.rcParams['font.sans-serif'] = [font]
      plt.rcParams['axes.unicode_minus'] = False
      return
      # 如果找不到特定字体,尝试使用通用解决方案
      plt.rcParams['font.sans-serif'] = ['sans-serif']
      plt.rcParams['axes.unicode_minus'] = False
      except:
      # 最终回退方案
      plt.rcParams['font.sans-serif'] = ['sans-serif']
      plt.rcParams['axes.unicode_minus'] = False

      设置字体

      set_chinese_font()

      生成模拟管理咨询数据

      np.random.seed(2023)
      def generate_project_data(name, revenue_base, utilization_rate, margin):
      """生成咨询项目数据"""
      revenue_data = np.random.normal(loc=revenue_base, scale=revenue_base*0.2, size=50)
      utilization_data = np.random.normal(loc=utilization_rate, scale=0.1, size=50)
      return {
      'name': name,
      'revenue': revenue_data,
      'utilization': utilization_data,
      'margin': margin,
      'color': ''
      }

      创建不同项目类型的数据

      projects = [
      generate_project_data('战略咨询', 500, 0.75, 0.35),
      generate_project_data('运营优化', 300, 0.85, 0.40),
      generate_project_data('数字化转型', 400, 0.80, 0.45),
      generate_project_data('人力资源咨询', 250, 0.90, 0.30)
      ]

      设置项目专属色系

      consulting_colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
      for i, project in enumerate(projects):
      project['color'] = consulting_colors[i]

      创建画布和子图

      fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 7), gridspec_kw={'width_ratios': [1, 1.5]})
      fig.suptitle('管理咨询项目分析', fontsize=18, fontweight='bold', y=0.98)

      第一图:战略咨询项目的收入分布

      target_project = projects[0]
      n, bins, patches = ax1.hist(
      target_project['revenue'],
      bins=10,
      alpha=0.85,
      color=target_project['color'],
      edgecolor='#333333',
      linewidth=1.2,
      label='战略咨询'
      )

      添加数字化转型项目收入分布作为对比

      ax1.hist(
      projects[2]['revenue'],
      bins=bins,
      alpha=0.45,
      color=projects[2]['color'],
      edgecolor='#333333',
      linewidth=1.0,
      hatch='//',
      label='数字化转型'
      )

      添加目标收入线

      target_revenue = 600
      ax1.axvline(x=target_revenue, color='#1A936F', linestyle='-', linewidth=2.5, alpha=0.9)
      ax1.text(target_revenue+20, ax1.get_ylim()[1]*0.9, f'目标收入: ¥{target_revenue}万',
      color='#1A936F', fontweight='bold')

      标记高利润区域

      high_margin_window = (400, 700)
      ax1.axvspan(high_margin_window[0], high_margin_window[1], alpha=0.08, color='green')
      ax1.text(high_margin_window[0]+50, ax1.get_ylim()[1]*0.75,
      f'高利润区域 ¥{high_margin_window[0]}-{high_margin_window[1]}万', color='#2ca02c')

      ax1.set_title(f"{target_project['name']}项目收入分布", fontsize=14)
      ax1.set_xlabel('项目收入 (万元)', fontsize=12)
      ax1.set_ylabel('项目数量', fontsize=12)
      ax1.grid(axis='y', linestyle=':', alpha=0.4)
      ax1.legend(loc='upper right')
      ax1.set_axisbelow(True)

      第二图:不同项目类型的顾问利用率对比

      bar_width = 0.35
      x = np.arange(len(projects))

      计算平均收入和使用率

      revenue_means = [np.mean(project['revenue']) for project in projects]
      utilization_means = [np.mean(project['utilization']) for project in projects]

      创建分组柱状图

      rects1 = ax2.bar(
      x - bar_width/2,
      revenue_means,
      bar_width,
      color=[project['color'] for project in projects],
      alpha=0.8,
      edgecolor='#333333',
      linewidth=1.0,
      label='平均收入'
      )

      rects2 = ax2.bar(
      x + bar_width/2,
      utilization_means * 1000, # 缩放比例以便在同一图表显示
      bar_width,
      color=[project['color'] for project in projects],
      alpha=0.95,
      edgecolor='#333333',
      linewidth=1.0,
      hatch='//',
      label='顾问利用率 (%)'
      )

      添加数值标签

      def autolabel(rects, ax, is_percent=False):
      for rect in rects:
      height = rect.get_height()
      value = height / 10 if is_percent else height
      ax.annotate(f'{value:.0f}{"%" if is_percent else ""}',
      xy=(rect.get_x() + rect.get_width() / 2, height),
      xytext=(0, 3), # 3点垂直偏移
      textcoords="offset points",
      ha='center', va='bottom',
      fontsize=10,
      fontweight='bold')

      autolabel(rects1, ax2)
      autolabel(rects2, ax2, is_percent=True)

      设置项目标签

      ax2.set_xticks(x)
      ax2.set_xticklabels([project['name'] for project in projects], fontsize=12)
      ax2.set_title('项目类型对比 (收入 vs 顾问利用率)', fontsize=14)
      ax2.set_ylabel('收入 (万元) / 利用率 (%)', fontsize=12)
      ax2.grid(axis='y', linestyle=':', alpha=0.3)
      ax2.legend(loc='upper left', framealpha=0.9)
      ax2.set_axisbelow(True)

      添加利润率

      for i, project in enumerate(projects):
      margin = project['margin'] * 100
      ax2.text(i, max(revenue_means[i], utilization_means[i]*1000) + 50,
      f'利润率: {margin:.0f}%',
      ha='center', fontsize=11, fontweight='bold',
      color='#E63946')

      添加数据说明

      current_date = datetime.now().strftime('%Y-%m-%d')
      analytics_text = (
      f"数据分析周期: 2023年1月-2023年6月 | 生成日期: {current_date}\n"
      "趋势洞察: 数字化转型项目利润率最高(45%),人力资源项目顾问利用率最高(90%)"
      )

      plt.figtext(0.5, 0.01, analytics_text,
      ha='center', fontsize=10.5, style='italic',
      bbox=dict(facecolor='#F8F9FA', edgecolor='#DEE2E6', alpha=0.8))

      布局优化

      plt.tight_layout(rect=[0, 0.03, 1, 0.95])

      添加版权信息

      plt.figtext(0.95, 0.01, "© 2023 管理咨询分析团队", ha='right', fontsize=9, alpha=0.7)

      保存和显示

      plt.savefig('consulting_project_analysis.png', dpi=120, bbox_inches='tight')
      plt.show()

相关推荐
huohaiyu2 分钟前
synchronized (Java)
java·开发语言·安全·synchronized
_OP_CHEN9 分钟前
C++基础:(九)string类的使用与模拟实现
开发语言·c++·stl·string·string类·c++容器·stl模拟实现
蓝天智能23 分钟前
QT MVC中View的特点及使用注意事项
开发语言·qt·mvc
松果集32 分钟前
【1】数据类型2
python
且慢.58941 分钟前
命令行的学习使用技巧
python
木觞清42 分钟前
喜马拉雅音频链接逆向实战
开发语言·前端·javascript
海琴烟Sunshine1 小时前
leetcode 66.加一 python
python·算法·leetcode
wuxuanok1 小时前
苍穹外卖 —— 公共字段填充
java·开发语言·spring boot·spring·mybatis
偷光1 小时前
浏览器中的隐藏IDE: Console (控制台) 面板
开发语言·前端·ide·php
罗橙7号1 小时前
【pyTorch】关于PyTorch的高级索引机制理解
人工智能·pytorch·python