分享

Matplotlib数据可视化:柱状图与直方图

 ml_Py 2021-12-08

柱状图和直方图是两种非常类似的统计图,区别在于:

  • 直方图展示数据的分布,柱状图比较数据的大小。

  • 直方图X轴为定量数据,柱状图X轴为分类数据。因此,直方图上的每个条形都是不可移动的,X轴上的区间是连续的、固定的。而柱状图上的每个条形是可以随意排序的,有的情况下需要按照分类数据的名称排列,有的则需要按照数值的大小排列。

  • 直方图柱子无间隔,柱状图条形有间隔

  • 直方图条形宽度可不一,柱状图条形宽度须一致。柱状图条形的宽度因为没有数值含义,所以宽度必须一致。但是在直方图中,条形的宽度代表了区间的长度,根据区间的不同,条形的宽度可以不同,但理论上应为单位长度的倍数。

本文将介绍matplotlib中柱状图和直方图的作图方法。

from matplotlib import pyplot as plt
import numpy as np
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 中文字体支持

1 bar()与barh()

matplotlib中提供了bar()和barh()两种方法画柱状图,bar()用来画垂直柱状图,barh()画水平柱状图,两者参数大同小异,如下所示:

2 垂直柱状图与水平柱状图

value= np.arange(6) ** 2
category = range(len(value))

fig = plt.figure(figsize=(84))

# 垂直柱状图
ax1 = fig.add_subplot(121)
ax1.set_title('图1 垂直柱状图')
ax1.bar(x=category, height=value)

# 垂直柱状图
ax2 = fig.add_subplot(122)
ax2.set_title('图2 水平柱状图')
ax2.barh(y=category, width=value)  # 注意这里参数名和值的传递与bar()不同

plt.show()

3 颜色、透明度与边框

value= np.arange(6) ** 2
category = range(len(value))

fig = plt.figure(figsize=(84))

# 垂直柱状图
ax1 = fig.add_subplot(121)
ax1.set_title('图1 垂直柱状图')
ax1.bar(x=category, height=value, 
        alpha=0.5,  # 透明度
        width=0.5,   # 每个条形的宽度
        color='yellow',  # 填充前景色
        edgecolor='red',  # 边框颜色
        linewidth=3  # 边框宽度
       )

# 垂直柱状图
ax2 = fig.add_subplot(122)
ax2.set_title('图2 水平柱状图')
ax2.barh(y=category, width=value,
         alpha=1,  # 透明度
         height=0.8,   # 每个条形的宽度
        color=['green''red''yellow''blue''grey''magenta'],  # 填充前景色
         linewidth=3  # 不显示边框
       )

plt.show()

4 刻度标签

value= np.arange(6) ** 2
category = range(len(value))

fig = plt.figure(figsize=(84))

# 垂直柱状图
ax1 = fig.add_subplot(121)
ax1.set_title('图1 垂直柱状图')
ax1.bar(x=category, height=value, 
        tick_label='类别'
       )

# 垂直柱状图
ax2 = fig.add_subplot(122)
ax2.set_title('图2 水平柱状图')
ax2.barh(y=category, width=value,
         tick_label=['类1''类2''类3''类4''类5''类6']
       )

plt.show()

5 添加误差线

means = (2035303527)  # 各组平均分
std = (23412)  # 组各标准差
label = ('第一组''第二组''第三种''第四组''第五组')
bar_width = 0.4
bar_x = np.arange(len(label)) 


fig = plt.figure(figsize=(84))


ax1 = fig.add_subplot(121)
bar1 = ax1.bar(x=bar_x, height=means, width=bar_width, color='green',
              yerr=std,  # 添加误差线
              ecolor='red',  # 误差线颜色
              capsize=5,  # 两端线段长短
               tick_label=label
             )

ax2 = fig.add_subplot(122)
bar2 = ax2.barh(y=bar_x, width=means, height=bar_width, color='green',
              xerr=std,  # 添加误差线
              ecolor='red',  # 误差线颜色
              capsize=5,  # 两端线段长短
              tick_label=label
             )

plt.show()

6 添加数据标注

means = (2035303527)  # 各组平均分
std = (23412)  # 组各标准差
label = ('第一组''第二组''第三种''第四组''第五组')
bar_width = 0.5
bar_x = np.arange(len(label)) 


fig = plt.figure(figsize=(104),tight_layout=True)


ax1 = fig.add_subplot(121)
bar1 = ax1.bar(x=bar_x, height=means, width=bar_width, color='green', tick_label=label
             )
for b in bar1:
        height = b.get_height()
        ax1.annotate('{}'.format(height),
                    xy=(b.get_x() + b.get_width() / 2, height),
                    xytext=(03),  # 3 points vertical offset
                    textcoords="offset points",color='red',
                    ha='center', va='bottom')

ax2 = fig.add_subplot(122)
bar2 = ax2.barh(y=bar_x, width=means, height=bar_width, color='green', tick_label=label
             )

for b in bar2:
        width = b.get_width()
        ax2.annotate('{}'.format(width),
                    xy=(width, b.get_y() + b.get_height() / 2),
                    xytext=(03),  # 3 points vertical offset
                    textcoords="offset points",color='red',
                    ha='left', va='center')

plt.show()

7 分组柱状图

menMeans = (2035303527)  # 男生各组平均分
womenMeans = (2532342025)# 女生各组平均分
menStd = (23412)  # 男生组各标准差
womenStd = (35233# 女生组各标准差
label = ('第一组''第二组''第三种''第四组''第五组')
bar_width = 0.4
bar_x = np.arange(len(label)) 


fig = plt.figure(figsize=(84))


ax = fig.add_subplot(111)
ax.set_title('图1 垂直柱状图')
bar1 = ax.bar(x=bar_x - bar_width/2,   # 设置不同的x起始位置
              height=menMeans, width=bar_width)
bar2 = ax.bar(x=bar_x + bar_width/2,   # 设置不同的x起始位置
              height=womenMeans, width=bar_width,
        )

ax.set_xlabel('组别')
ax.set_ylabel('分数')
ax.set_title('各组不同性别分数')
ax.set_xticks(range(5))
ax.set_xticklabels(label)
ax.set_yticklabels(np.arange(08110))
ax.legend((bar1, bar2), ('男生''女生'))

plt.show()

8 堆叠柱状图

menMeans = (2035303527)  # 男生各组平均分
womenMeans = (2532342025)# 女生各组平均分
menStd = (23412)  # 男生组各标准差
womenStd = (35233# 女生组各标准差
label = ('第一组''第二组''第三种''第四组''第五组')
bar_width = 0.4
bar_x = np.arange(len(label)) 

fig = plt.figure(figsize=(84))


ax = fig.add_subplot(111)
ax.set_title('图1 垂直柱状图')
bar1 = ax.bar(x=bar_x, height=menMeans, width=bar_width)
bar2 = ax.bar(x=bar_x, height=womenMeans, width=bar_width,
        bottom=menMeans # 通过bottom参数设置起始位置, 起始位置就是下半部分(bar1)条形的高度
        )

ax.set_xlabel('组别')
ax.set_ylabel('分数')
ax.set_title('各组不同性别分数')
ax.set_xticks(range(5))
ax.set_xticklabels(label)
ax.set_yticklabels(np.arange(08110))
ax.legend((bar1, bar2), ('男生''女生'))

plt.show()

9 直方图

直方图的绘制是通过hist()方法完成。hist()方法参数很多,来看看主要的参数:

data_x = [13198125131124139131117128108135138131102107114119128121142127130124,
   10111011611711012812811599136126134951381171117813212411315011011786,
   951441051261301261301261161231061121381238610199136123117119105137,
   123128125104109134125127105120107129116108132103136118102120114105115,
   13214511912111213912513810913213415610611712714413913911914083110102,
   123107143115136118139123112118125109119133112114122109106123116131127,
   11511811213511514613711610314483123111110111100154136100118119133134,
   106129126110111109141120117106149122122110118127121114125126114140103,
   1301411171061141211141331379212111214697137105981171128197139113134,
   1061441101371371111041171001111011101051291371121201131331128394146,
   13310113111611184137115122106144109123116111111133150]

fig = plt.figure(figsize=(84))

ax1 = fig.add_subplot(121)
hists1 = ax1.hist(x=data_x, bins=5)  # 等距划分

ax2 = fig.add_subplot(122)
hists2 = ax2.hist(x=data_x,bins=[78,90,100,120,140,145,150])

plt.show()

hist()方法将会返回一个包含三个元素的数组,第一个元素为每个条形区间中元素的数量,第二个元素为区间的边界,第三个元素为Patch实例化对象。

hists1
(array([ 9., 49., 97., 77., 18.]),
array([ 78. , 93.6, 109.2, 124.8, 140.4, 156. ]),
<a list of 5 Patch objects>)

作者:奥辰
Github:https://github.com/ChenHuabin321
https://www.cnblogs.com/chenhuabin


加入机器学习微信群

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多