作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
欢迎加入社区:码上找工作
作者专栏每日更新:
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级
假设大消费场景有一个公司一组销售人员的数据,包括每个销售代表的销售额和他们达成销售目标的比率。我们的目的是展示销售代表的表现,并突出表现最好和最差的销售代表。
分析目标
我们的分析目标是评估一个销售团队的表现,特别是识别出表现最好和最差的销售代表,并了解他们相对于销售目标的具体表现。
分析步骤
- 数据模拟:首先,我们模拟了一组包含销售代表销售额和销售目标达成率的数据。
- 初步可视化:接着,我们使用复杂的条形图和折线图结合,尝试同时展示销售额和销售目标达成情况。
- 分析与改进:基于初步图表的复杂性和信息过载,我们决定简化图表设计,更直接地呈现关键数据。
数据模拟与可视化
改进前
使用Python,我们生成了销售代表的销售额和销售目标达成率的模拟数据。初步的可视化尝试通过一个复合图表来展示这些信息,但发现图表过于复杂,难以一眼看出核心信息。
这是我们经常会用的双轴图,我们来看下这个双轴图有哪些不清晰的
- 过度复杂:通过同时使用条形图展示销售额和折线图展示销售目标达成率,图表变得过于复杂。对于看的人来说,需要同时解读两种不同的图表元素和它们各自的数值范围,这增加了理解的难度需要看的很仔细猜哪个Y轴是销售额。
- 信息过载:尽管提供了大量数据点,但太多的信息反而使得观众难以快速抓住核心信息——哪些销售代表的表现超出或未达到预期。读者可能需要花费额外的时间和精力去分辨哪些信息是他们真正关心的。 视觉分散:使用两种颜色(一种用于条形图,另一种用于折线图)和两种不同的图表类型在同一视图中,可能会导致视觉上的混乱。观众的注意力可能在两种图表元素间摇摆,难以集中于最重要的洞察。 核心信息不突出:在这种复合图表中,虽然数据全面,但核心信息——谁是表现最好和最差的销售代表,以及他们相对于销售目标的具体表现——并没有得到有效的突出。这使得快速做出决策或识别行动点变得更加困难。 图表利用空间不佳:在某些情况下,图表中的图例或其他注释可能会不小心遮挡一部分数据(如条形的一部分),进一步降低了图表的可读性和实用性。
第一次改进
基于这些问题我们调整一下把折线图去掉,达成目标的用绿色展示,不达成目标的用红色展示,这样能看出来哪些销售达成目标哪些销售不达成目标相比之前会更清晰一些,从双轴图改成单轴图看着稍微清晰一些,但是一人没解决距离目标的差异,因为不同销售的目标可能不一样
第二次改进
更清楚地展示每位销售代表的表现细节。但是大家看看这个图有什么问题,也能看到目标的差异,没有双轴图这么多信息。就是还是要让人去看几遍才能比较清楚销售达成最好的和销售达成最不好的,要让读者反复看的表都能改进
第三次改进(突出重点)
一眼能看到想要的信息 Rep6 这个销售代表要降工资,Rep10 要考虑涨工资了
图表设计的简化:
去除网格线:为了减少视觉上的干扰,我们决定去除背景的网格线,使得关注点更集中于数据本身。
统一条形图颜色:通过使用灰色作为主要的条形图颜色,并用绿色和红色分别高亮表现最好和最差的销售代表,我们简化了视觉解读过程,使得观众能够迅速识别关键信息。
关键数据的突出显示:
最佳与最差表现者的高亮:通过特别用色(绿色表示最佳表现,红色表示最差表现),直观地突出了表现最佳和最差的销售代表,使得这些关键信息在第一时间内就能被捕获。
销售目标的直观对比:在每个条形上,我们通过暗红色的虚线表示了销售目标,使得销售额与目标之间的对比变得直观明显。这种设计帮助观众快速评估每位销售代表的表现。
具体差异的明确标注:
数值标注:每个条形旁边的文本注释清晰地显示了销售额超出或低于目标的具体数值,提供了量化的表现评估。这使得除了直观的视觉比较外,观众还能获取精确的数值信息。
总之,改进后的图表展示了如何通过精心设计的数据可视化手段,有效地传达关键商业洞察,从而支持更加明智的业务决策制定。这一过程强调了在数据分析和可视化领域中,简化和清晰度的重要性
改进前后对比
练习的excel数据欢迎关注微信公众号 数据分析螺丝钉 回复关键词 python可视化 领取,有更多免费学习资源一起进步
python代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 重新生成一致的模拟数据 np.random.seed(1) # 确保数据的一致性 sales_reps = ['Rep' + str(i) for i in range(1, 11)] sales_amounts = np.random.uniform(80, 120, 10) sales_targets = np.random.uniform(0.8, 1.2, 10) df_sales = pd.DataFrame({'SalesRep': sales_reps, 'SalesAmount': sales_amounts, 'SalesTarget': sales_targets}) df_sales['TargetAmount'] = 100 * df_sales['SalesTarget'] df_sales['Diff'] = df_sales['SalesAmount'] - df_sales['TargetAmount'] best_rep = df_sales.loc[df_sales['Diff'].idxmax()] worst_rep = df_sales.loc[df_sales['Diff'].idxmin()] # 改进前的复合图表代码 fig, ax1 = plt.subplots(figsize=(12, 6)) color = 'tab:blue' ax1.set_xlabel('Sales Representative') ax1.set_ylabel('Sales Amount ($K)', color=color) ax1.bar(df_sales['SalesRep'], df_sales['SalesAmount'], color=color) ax1.tick_params(axis='y', labelcolor=color) ax2 = ax1.twinx() color = 'tab:red' ax2.set_ylabel('Sales Target Achievement', color=color) ax2.plot(df_sales['SalesRep'], df_sales['SalesTarget'], color=color, marker='o', linestyle='dashed') ax2.tick_params(axis='y', labelcolor=color) fig.tight_layout() plt.show() # 显示改进前的图表 # 改进后的图表代码,去掉网格线 plt.figure(figsize=(14, 7)) bars = plt.bar(df_sales['SalesRep'], df_sales['SalesAmount'], color='gray', label='Sales Amount') plt.bar(best_rep['SalesRep'], best_rep['SalesAmount'], color='green', label='Best Performance') plt.bar(worst_rep['SalesRep'], worst_rep['SalesAmount'], color='red', label='Worst Performance') for i, bar in enumerate(bars): plt.hlines(df_sales['TargetAmount'][i], xmin=bar.get_x(), xmax=bar.get_x() + bar.get_width(), colors='darkred', linestyles='--', lw=2) for i in range(len(df_sales)): diff = df_sales['Diff'][i] color = 'green' if diff >= 0 else 'red' plt.text(i, df_sales['SalesAmount'][i] + 5, f'{diff:.2f}', ha='center', color=color) plt.xlabel('Sales Representative') plt.ylabel('Sales Amount ($K)') plt.title('Enhanced Chart with Best and Worst Performers Highlighted') plt.ylim(0, max(df_sales['SalesAmount']) + 20) plt.legend(loc='upper left') plt.grid(False) # 禁用网格线 plt.show() # 显示改进后的图表