python matplotlib 堆积柱形图/双柱形图/横条柱状图/折线图

使用 Matplotlib 提供的 bar() 函数来绘制柱状图。与前面介绍的 plot() 函数类似,程序每次调用 bar() 函数时都会生成一组柱状图, 如果希望生成多组柱状图,则可通过多次调用 bar() 函数来实现。

(1)下面程序使用堆积柱状图来展示《C语言基础》和《Java基础》两套教程历年的销量数据
import matplotlib.pyplot as plt
02.import numpy as np
03.
04.# 构建数据
05.x_data = ['2012', '2013', '2014', '2015', '2016', '2017', '2018']
06.y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
07.y_data2 = [52000, 54200, 51500,58300, 56800, 59500, 62700]
08.# 绘图
09.plt.bar(x=x_data, height=y_data, label='C语言基础', color='steelblue', alpha=0.8)
10.plt.bar(x=x_data, height=y_data2, label='Java基础', color='indianred', alpha=0.8)
11.# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式
12.for x, y in enumerate(y_data):
13.    plt.text(x, y + 100, '%s' % y, ha='center', va='bottom')
14.for x, y in enumerate(y_data2):
15.    plt.text(x, y + 100, '%s' % y, ha='center', va='top')
16.# 设置标题
17.plt.title("Java与Android图书对比")
18.# 为两条坐标轴设置名称
19.plt.xlabel("年份")
20.plt.ylabel("销量")
21.# 显示图例
22.plt.legend()
23.plt.show()

上面程序中,第 9、10 两行代码用于在数据图上生成两组柱状图,程序设置了这两组柱状图的颜色和透明度。

在使用 bar() 函数绘制柱状图时,默认不会在柱状图上显示具体的数值。为了能在柱状图上显示具体的数值,程序可以调用 text() 函数在数据图上输出文字,如上面程序中第 10 行代码所示。

在使用 text() 函数输出文字时,该函数的前两个参数控制输出文字的 X、Y 坐标,第三个参数则控制输出的内容。其中 va 参数控制文字的垂直对齐方式,ha 参数控制文字的水平对齐方式。

对于上面的程序来说,由于 X 轴数据是一个字符串列表,因此 X 轴实际上是以列表元素的索引作为刻度值的。因此,当程序指定输出文字的 X 坐标为 0 时,表明将该文字输出到第一个条柱处;对于 Y 坐标而言,条柱的数值正好在条柱高度所在处,如果指定 Y 坐标为条柱的数值 +100,就是控制将文字输出到条柱略上一点的位置。

运行上面程序,可以看到如图 1 所示的效果。
果。

柱状图.png

图 1 两组柱状图

(2)下面程序使用双柱状图来展示《C语言基础》和《Java基础》两套教程历年的销量数据

从图 1 所示的显示效果来看,第二次绘制的性状图完全与第一次绘制的柱状图重叠,这并不是我们期望的结果,我们希望每组数据的条柱能并列显示。

为了实现条柱井列显示的效果,首先分析条柱重叠在一起的原因。使用 Matplotlib 绘制柱状图时同样也需要 X 轴数据,本程序的 X 轴数据是元素为字符串的 list 列表,因此程序实际上使用各字符串的索引作为 X 轴数据。比如 '2011' 字符串位于列表的第一个位置,因此代表该条柱的数据就被绘制在 X 轴的刻度值1处(由于两个柱状图使用了相同的 X 轴数据,因此它们的条柱完全重合在一起)。

为了将多个柱状图的条柱并列显示,程序需要为这些柱状图重新计算不同的 X 轴数据。为了精确控制条柱的宽度,程序可以在调用 bar() 函数时传入 width 参数,这样可以更好地计算条柱的并列方式。将上面程序改为如下形式:

import numpy as np
# 构建数据
x_data = ['2011', '2012', '2013', '2014', '2015', '2016', '2017']
y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
y_data2 = [52000, 54200, 51500,58300, 56800, 59500, 62700]
bar_width=0.3
# 将X轴数据改为使用range(len(x_data), 就是0、1、2...
plt.bar(x=range(len(x_data)), height=y_data, label='C语言基础',
color='steelblue', alpha=0.8, width=bar_width)
# 将X轴数据改为使用np.arange(len(x_data))+bar_width,
# 就是bar_width、1+bar_width、2+bar_width...这样就和第一个柱状图并列了
plt.bar(x=np.arange(len(x_data))+bar_width, height=y_data2,
label='Java基础', color='indianred', alpha=0.8, width=bar_width)
# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式
for x, y in enumerate(y_data):
plt.text(x, y + 100, '%s' % y, ha='center', va='bottom')
for x, y in enumerate(y_data2):
plt.text(x+bar_width, y + 100, '%s' % y, ha='center', va='top')
plt.xticks(np.arange(len(x_data))+bar_width/2, x_data)
# 设置标题
plt.title("C与Java对比")
# 为两条坐标轴设置名称
plt.xlabel("年份")
plt.ylabel("销量")
# 显示图例
plt.legend()
plt.show()

该程序与前一个程序的区别就在于第 10、14 两行代码,这两行代码使用了不同的 x 参数,其中第一个柱状图的 X 轴数据为 range(len(x_data)),也就是 0、1、2…,这样第一个柱状图的各条柱恰好位于 0、1、2… 刻度值处;第二个柱状图的 X 轴数据为 np.arange(len(x_data))+bar_width,也就是 bar_width、1+bar_width、2+bar_width···,这样第二个柱状图的各条柱位于 0、1、2…刻度值的偏右一点 bar_width 处,这样就恰好与第一个柱状图的各条柱并列了。

运行上面程序,将会发现该柱状图的 X 轴的刻度值变成 0、1、2 等值,不再显示年份。为了让柱状图的 X 轴的刻度值显示年份,程序可以调用 xticks() 函数重新设置 X 轴的刻度值。

例如,在程序中添加如下代码:

为X轴设置刻度值

plt.xticks(np.arange(len(x_data))+bar_width/2, x_data)
上面代码使用 x_data 为 X 轴设置刻度值,第一个参数用于控制各刻度值的位置,该参数是 np.arange(len(x_data))+bar_width/2,也就是 bar_width/2、1+bar_width/2、2+bar_width/2 等,这样这些刻度值将被恰好添加在两个条柱之间。

运行上面程序可看到如图 2 所示的运行结果:


柱状图1.png

有些时候,可能希望两个条柱之间有一点缝隙,那么程序只要对第二个条柱的 X 轴数据略做修改即可。例如,将上面程序中第 14 行代码改为如下形式:

plt.bar(x=np.arange(len(x_data))+bar_width+0.05, height=y_data2,
label='Java基础', color='indianred', alpha=0.8, width=bar_width)

上面代码重新计算了 X 轴数据,使用 np.arange(len(x_data))+bar_width+0.05 作为 X 轴数据,因此两组柱状图的条柱之间会有 0.05 的距离。

(3)Matplotlib 绘制水平柱状图

调用 Matplotlib 的 barh() 函数可以生成水平柱状图。barh() 函数的用法与 bar() 函数的用法基本一样,只是在调用 barh() 函数时使用 y参数传入 Y 轴数据,使用 width 参数传入代表条柱宽度的数据。

例如,如下程序调用 barh() 函数生成两组并列的水平柱状图,来展示两套教程历年的销量统计数据:

import matplotlib.pyplot as plt
import numpy as np

# 构建数据
x_data = ['2011', '2012', '2013', '2014', '2015', '2016', '2017']
y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
y_data2 = [52000, 54200, 51500,58300, 56800, 59500, 62700]
bar_width=0.3
# Y轴数据使用range(len(x_data), 就是0、1、2...
plt.barh(y=range(len(x_data)), width=y_data, label='Java基础教程',
color='steelblue', alpha=0.8, height=bar_width)
# Y轴数据使用np.arange(len(x_data))+bar_width,
# 就是bar_width、1+bar_width、2+bar_width...这样就和第一个柱状图并列了
plt.barh(y=np.arange(len(x_data))+bar_width, width=y_data2,
label='C语言基础', color='indianred', alpha=0.8, height=bar_width)
# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式
for y, x in enumerate(y_data):
plt.text(x+5000, y-bar_width/2, '%s' % x, ha='center', va='bottom')
for y, x in enumerate(y_data2):
plt.text(x+5000, y+bar_width/2, '%s' % x, ha='center', va='bottom')
# 为Y轴设置刻度值
plt.yticks(np.arange(len(x_data))+bar_width/2, x_data)
# 设置标题
plt.title("Java与C对比")
# 为两条坐标轴设置名称
plt.xlabel("销量")
plt.ylabel("年份")
# 显示图例
plt.legend()
plt.show()

上面程序中,第 10 行代码使用 barh() 函数来创建水平柱状图,其中 y 参数为 range(len(x_data)),这意味着这些条柱将会沿着 Y 轴均匀分布;而 width 参数为 y_data,这意味着 y_data 列表所包含的数值会决定各条柱的宽度。第 14 行代码的控制方式与此类似。
运行上面程序,可以看到如图 3 所示的效果

横条图.png
(4.1)折线图

折线图与柱状图很像,它们只是表现数据的方式不同,柱状图使用条柱代表数据,而折线图则使用折线点来代表数据。因此,生成折线图的方式与生成柱状图的方式基本相同。
使用 pygal.Line 类来表示折线图,程序创建 pygal.Line 对象就是创建折线图。下面程序示范了利用折线图来展示两套教程销量统计数据的方法。

import pygal
x_data = ['2011', '2012', '2013', '2014', '2015', '2016', '2017']
# 构造数据
 y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
 y_data2 = [52000, 54200, 51500,58300, 56800, 59500, 62700]
 # 创建pygal.Line对象(折线图)
 line = pygal.Line()
 # 添加两组代表折线的数据
 line.add('C语言教程', y_data)
 line.add('Python教程', y_data2)
 #设置X轴的刻度值
 line.x_labels = x_data
 # 重新设置Y轴的刻度值
 line.y_labels = [20000, 40000, 60000, 80000, 100000]
 line.title = '编程教程的历年销量'
 # 设置X、Y轴的标题
 line.x_title = '年份'
 line.y_title = '销量'
 #设置将图例放在底部
 line.legend_at_bottom = True
 # 指定将数据图输出到SVG文件中
 line.render_to_file('fk_books.svg')

上面程序中的第 8 行代码创建了 pygal.Line 对象,该对象代表折线图。接下来程序调用 pygal.Line 对象的 add() 方法添加统计数据,然后对数据图进行配置。
运行上面程序,将会生成如图 1 所示的折线图。


折现图.png
(4.2)折线图

plot() 函数除了支持创建具有单条折线的折线图,也支持创建包含多条折线的复式折线图,只要在调用 plot() 函数时传入多个分别代表 X 轴和 Y 轴数据的 list 列表即可。例如如下程序:

 import matplotlib.pyplot as plt
 x_data = ['2013', '2014', '2015', '2016', '2017', '2018', '2019']
# 定义2个列表分别作为两条折线的Y轴数据
y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
y_data2 = [52000, 54200, 51500,58300, 56800, 59500, 62700]
# 传入2组分别代表X轴、Y轴的数据
plt.plot(x_data, y_data, x_data, y_data2)
# 调用show()函数显示图形
plt.show()

上面程序在调用 plot() 函数时,传入了两组分别代表 X 轴、Y 轴数据的 list 列表,因此该程序可以显示两条折线,如图 3 所示。


多条折线图.png

3:---画图(同时画两幅图)
通过统计出每个年收入段贷款如期还款笔数和违约笔数,并计算出每段贷款如期还款笔数和违约笔数所占的比例

loanData[['Status']]incomeRage = loanData.groupby(['Status', 'IncomeRange'])['Status'].count().unstack(0)
index = ['Not displayed', 'Not employed', '$1-24,999', '$25,000-49,999', '$50,000-74,999', '$75,000-99,999', '$100,000+']
incomeRage = incomeRage[['Completed','Defaulted']].reindex(index)#配置索引

在用pandas进行数据重排时,经常用到stack和unstack两个函数。stack的意思是堆叠,堆积,unstack即“不要堆叠”,我对两个函数是这样理解和区分的。
常见的数据的层次化结构有两种,一种是表格,一种是“花括号”,即下面这样的l两种形式:
常见的数据的层次化结构有两种,一种是表格,一种是“花括号”,即下面这样的l两种形式:

坏账百分之=(坏账/坏账+正常)

defaultRate = (incomeRage['Defaulted'] / (incomeRage['Defaulted'] + incomeRage['Completed'])).reindex(index)#print(defaultRate)#坏账百分之
defaultRate1=defaultRate[['Not displayed','Not employed','$1-24,999','$25,000-49,999','$50,000-74,999','$75,000-99,999','$100,000+',]]#剔除$0为空NaN的值
print(defaultRate1)#坏账百分之
    # 违约率情况
    y = list(defaultRate1.values)#Dafrme转为list
    fig1 = plt.figure(1)
    # fig1.set_size_inches(15.5, 7.5)
    ax1 = fig1.add_subplot(2, 1, 2)
    x = np.arange(len(index)) + 1
    ax1.bar(x, y, width=0.4)
    ax1.set_xticks(x)
    ax1.set_xticklabels(index, rotation=0, fontsize=12)
    ax1.set_ylabel('违约百分率(%)', fontsize=14)
    for a, b in zip(x, y):
        plt.text(a, b + 0.001, '%.2f%%' % (b * 100), ha='center', va='bottom', fontsize=10)
    ax2 = fig1.add_subplot(2, 1, 1)
    incomeRage.plot(kind='bar', ax=ax2)
    ax2.set_xticklabels(index, rotation=0, fontsize=12)
    ax2.set_ylabel('数量', fontsize=14)
    plt.show()
123.png

4:--画图(双正态分布图叠加)
按照常识来说债务收入比(DebtToIncomeRatio)低的人更具备还款能力,违约可能性应该低于债务收入比高的人。

 DefaultedRatio=loanData[loanData['Status']=='Defaulted']['DebtToIncomeRatio']
 CompletedRatio=loanData[loanData['Status']=='Completed']['DebtToIncomeRatio']
 print(DefaultedRatio.shape)
 print(CompletedRatio.shape)
 ax=CompletedRatio.hist(bins=1000,color='g',label='Compeleted')
 ax=DefaultedRatio.hist(bins=1000,color='b',label='Defaulted')
 ax.set_xlim([0,1])
 plt.xlabel('DebtToIncomeRatio',fontsize=14)
 plt.ylabel('数量',fontsize=14)
 plt.legend(loc='best')
 plt.show()
456.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342