介绍

对于绘制某些类型的数据来说,瀑布图是一种十分有用的工具。不足为奇的是,我们可以使用Pandas和matplotlib创建一个可重复的瀑布图。

在往下进行之前,我想先告诉大家我指代的是哪种类型的图表。我将建立一个维基百科文章中描述的2D瀑布图。

这种图表的一个典型的用处是显示开始值和结束值之间起“桥梁”作用的+和-的值。因为这个原因,财务人员有时会将其称为一个桥梁。跟我之前所采用的其他例子相似,这种类型的绘图在Excel中不容易生成,当然肯定有生成它的方法,但是不容易记住。

关于瀑布图需要记住的关键点是:它本质上是一个堆叠在一起的条形图,不过特殊的一点是,它有一个空白底栏,所以顶部栏会“悬浮”在空中。那么,让我们开始吧。

创建图表

首先,执行标准的输入,并确保IPython能显示matplot图。

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

%matplotlib inline

设置我们想画出瀑布图的数据,并将其加载到数据帧(DataFrame)中。

数据需要以你的起始值开始,但是你需要给出最终的总数。我们将在下面计算它。

index = ['sales','returns','credit fees','rebates','late charges','shipping']

data = {'amount': [350000,-30000,-7500,-25000,95000,-7000]}

trans = pd.DataFrame(data=data,index=index)

我使用了IPython中便捷的display函数来更简单地控制我要显示的内容。

from IPython.display import display

display(trans)

瀑布图的最大技巧是计算出底部堆叠条形图的内容。有关这一点,我从stackoverflow上的讨论中学到很多。

首先,我们得到累积和。

display(trans.amount.cumsum())

sales 350000

returns 320000

credit fees 312500

rebates 287500

late charges 382500

shipping 375500

Name: amount, dtype: int64

这看起来不错,但我们需要将一个地方的数据转移到右边。

blank=trans.amount.cumsum().shift(1).fillna(0)

display(blank)

sales 0

returns 350000

credit fees 320000

rebates 312500

late charges 287500

shipping 382500

Name: amount, dtype: float64

我们需要向trans和blank数据帧中添加一个净总量。

total = trans.sum().amount

trans.loc["net"] = total

blank.loc["net"] = total

display(trans)

display(blank)

sales 0

returns 350000

credit fees 320000

rebates 312500

late charges 287500

shipping 382500

net 375500

Name: amount, dtype: float64

创建我们用来显示变化的步骤。

step = blank.reset_index(drop=True).repeat(3).shift(-1)

step[1::3] = np.nan

display(step)

0 0

0 NaN

0 350000

1 350000

1 NaN

1 320000

2 320000

2 NaN

2 312500

3 312500

3 NaN

3 287500

4 287500

4 NaN

4 382500

5 382500

5 NaN

5 375500

6 375500

6 NaN

6 NaN

Name: amount, dtype: float64

对于“net”行,为了不使堆叠加倍,我们需要确保blank值为0。

blank.loc["net"] = 0

然后,将其画图,看一下什么样子。

my_plot = trans.plot(kind='bar', stacked=True, bottom=blank,legend=None, title="2014 Sales Waterfall")

my_plot.plot(step.index, step.values,'k')

看起来相当不错,但是让我们试着格式化Y轴,以使其更具有可读性。为此,我们使用FuncFormatter和一些Python2.7+的语法来截断小数并向格式中添加一个逗号。

def money(x, pos):

'The two args are the value and tick position'

return "${:,.0f}".format(x)

from matplotlib.ticker import FuncFormatter

formatter = FuncFormatter(money)

然后,将其组合在一起。

my_plot = trans.plot(kind='bar', stacked=True, bottom=blank,legend=None, title="2014 Sales Waterfall")

my_plot.plot(step.index, step.values,'k')

my_plot.set_xlabel("Transaction Types")

my_plot.yaxis.set_major_formatter(formatter)

完整脚本

基本图形能够正常工作,但是我想添加一些标签,并做一些小的格式修改。下面是我最终的脚本:

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from matplotlib.ticker import FuncFormatter

#Use python 2.7+ syntax to format currency

def money(x, pos):

'The two args are the value and tick position'

return "${:,.0f}".format(x)

formatter = FuncFormatter(money)

#Data to plot. Do not include a total, it will be calculated

index = ['sales','returns','credit fees','rebates','late charges','shipping']

data = {'amount': [350000,-30000,-7500,-25000,95000,-7000]}

#Store data and create a blank series to use for the waterfall

trans = pd.DataFrame(data=data,index=index)

blank = trans.amount.cumsum().shift(1).fillna(0)

#Get the net total number for the final element in the waterfall

total = trans.sum().amount

trans.loc["net"]= total

blank.loc["net"] = total

#The steps graphically show the levels as well as used for label placement

step = blank.reset_index(drop=True).repeat(3).shift(-1)

step[1::3] = np.nan

#When plotting the last element, we want to show the full bar,

#Set the blank to 0

blank.loc["net"] = 0

#Plot and label

my_plot = trans.plot(kind='bar', stacked=True, bottom=blank,legend=None, figsize=(10, 5), title="2014 Sales Waterfall")

my_plot.plot(step.index, step.values,'k')

my_plot.set_xlabel("Transaction Types")

#Format the axis for dollars

my_plot.yaxis.set_major_formatter(formatter)

#Get the y-axis position for the labels

y_height = trans.amount.cumsum().shift(1).fillna(0)

#Get an offset so labels don't sit right on top of the bar

max = trans.max()

neg_offset = max / 25

pos_offset = max / 50

plot_offset = int(max / 15)

#Start label loop

loop = 0

for index, row in trans.iterrows():

# For the last item in the list, we don't want to double count

if row['amount'] == total:

y = y_height[loop]

else:

y = y_height[loop] + row['amount']

# Determine if we want a neg or pos offset

if row['amount'] > 0:

y += pos_offset

else:

y -= neg_offset

my_plot.annotate("{:,.0f}".format(row['amount']),(loop,y),ha="center")

loop+=1

#Scale up the y axis so there is room for the labels

my_plot.set_ylim(0,blank.max()+int(plot_offset))

#Rotate the labels

my_plot.set_xticklabels(trans.index,rotation=0)

my_plot.get_figure().savefig("waterfall.png",dpi=200,bbox_inches='tight')

运行该脚本将生成下面这个漂亮的图表:

最后的想法

如果你之前不熟悉瀑布图,希望这个示例能够向你展示它到底是多么有用。我想,可能一些人会觉得对于一个图表来说需要这么多的脚本代码有点糟糕。在某些方面,我同意这种想法。如果你仅仅只是做一个瀑布图,而以后不会再碰它,那么你还是继续用Excel中的方法吧。

然而,如果瀑布图真的很有用,并且你需要将它复制给100个客户,将会怎么样呢?接下来你将要怎么做呢?此时使用

Excel将会是一个挑战,而使用本文中的脚本来创建100个不同的表格将相当容易。再次说明,这一程序的真正价值在于,当你需要扩展这个解决方案时,它

能够便于你创建一个易于复制的程序。

我真的很喜欢学习更多Pandas、matplotlib和IPothon的知识。我很高兴这种方法能够帮到你,并希望其他人也可以从中学习到一些知识,并将这一课所学应用到他们的日常工作中。

来源:51CTO

python堆叠瀑布图怎么做_教你用Python创建瀑布图相关推荐

  1. python瀑布图怎么做_教你用Python创建瀑布图

    介绍 对于绘制某些类型的数据来说,瀑布图是一种十分有用的工具.不足为奇的是,我们可以使用Pandas和matplotlib创建一个可重复的瀑布图. 在往下进行之前,我想先告诉大家我指代的是哪种类型的图 ...

  2. sip 时序图_时序图怎么看_教你如何看懂时序图 - 什么是时序图_时序图怎么看_教你如何看懂时序图...

    时序图怎么看_教你如何看懂时序图 操作时序永远使用是任何一片IC芯片的最主要的内容.一个芯片的所有使用细节都会在它的官方器件手册上包含.所以使用一个器件事情,要充分做好的第一件事就是要把它的器件手册上 ...

  3. python中的画布背景设置_教你用python画图—Turtle详细教程

    Turtle模块绝对是吸引非专业代码开发者人员学习python入门的好工具 通过turtle几行代码的执行软件就会画出漂亮的图形,美观而且有成就感,这样一下子对python编程就产生了兴趣. 这些漂亮 ...

  4. python能做出exe程序么_教你用python做exe程序

    pyinstaller是一个python扩展包,可以将python文件转换成exe文件,这样就可以实现在没有python的环境下运行想运行的程序啦! 也可以用python做一个windows桌面应用程 ...

  5. python小海龟画房子编程_教孩子学Python编程之海龟画图(一)

    大家好,我是践行计算机教育刘老师,很高兴跟大家分享Python编程,建议5年级以上的学生学习.父母也可以陪着孩子一起学习Python编程,对于孩子学编程起到监督和辅助学习.下载我们Python编程工具 ...

  6. 用python画小猪佩奇动画片全集_教你用Python画小猪佩奇

    刚过去几个月大家票圈肯定都被"小猪佩奇"."社会人"等字样刷屏了,不知道啥时候开始小猪佩奇成立社会人的标志,我说不出个所以然.但是相信很多人和我一样没有看过这系 ...

  7. python爬虫股票分析准不准_教你用Python爬虫股票评论,简单分析股民用户情绪

    这里是文件夹列表 main(); function main(){ var stocknum = 600000; getDate(stocknum); } function getDate(stock ...

  8. python concat函数 多张表_教你用python递归函数求n的阶乘,优缺点及递归次数设置方式

    本文内容介绍了python递归函数求n的阶乘,优缺点及递归次数设置方式,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧! 递归函数两大特点: 1.能够调用函数自身 2.至少有一个出口( ...

  9. python 查看已经安装的模块_教你用Python查看模块的帮助文档,方法和帮助信息...

    这里介绍下python自带的查看帮助功能,可以在编程时不中断地迅速找到所需模块和函数的使用方法 查看方法 通用帮助函数help() python中的help()类似unix中的man指令,熟悉后会对我 ...

最新文章

  1. STM32使用另外两种方法使LED灯闪烁
  2. php点击按钮显示隐藏代码,jQuery中点击按钮实现显示与隐藏的方法
  3. Parsing error: The keyword 'const' is reservedeslint
  4. android判断sd u盘,[Android Framework]获取U盘 SD 状态
  5. iQOO Neo5游戏评测,配置独显的手机表现如何?
  6. JetBrains AppCode:用于 iOS/macOS 开发的智能 IDE
  7. Python 多进程multiprocessing
  8. 人人影视路由二代刷Breed
  9. excel转置怎么操作_Excel里掌握这些小技巧,让你的工作更轻松
  10. Word排版插件,VSTO公文排版,Word论文排版
  11. [Intensive Reading]图像生成:SaGAN
  12. 小鲲Python嘎嘎炫~day1.4
  13. 批处理删除注册表分支方法
  14. js滚动到指定位置显示或隐藏元素
  15. 钢琴 |《小汤普森简易钢琴教程》第一册
  16. 响应式织梦模板律师事务所网站
  17. OSChina 周二乱弹 ——人和人之间的关系用通话时间来表述
  18. cvs配电保护断路器_CVS100F断路器|施耐德CVS100F100A断路器
  19. PCB学习笔记——PCB的铺铜方法
  20. VB 2010 (6) date datetime dateandtime

热门文章

  1. 计算机hppusg.exe应用程序错误,win10系统提示“txupd.exe应用程序错误”的两种解决方法...
  2. 大数据:技术与应用实践指南(中国工程院院士倪光南倾情作序,雷万云、毛新生、段永朝、安晖联合力荐)...
  3. python3 基础二——基本的数据类型三
  4. Neo4j · 建立2022年的中国电影图谱
  5. java枚举注释_【Java】枚举类和注解
  6. 做SEO技术如何不被人割韭菜?
  7. 计算机桌面清理用于什么,教你如何整理桌面
  8. oracle11G与10G网络通信差异
  9. 时间插件只能选择整点和半点_【海王刷出攻略】记住这几个时间点,捕鱼大佬从此诞生...
  10. fedora 下 wine 运行酷我音乐盒