草庐IT

100天精通Python(可视化篇)——第84天:matplotlib绘制不同种类炫酷直方图参数说明+代码实战(普通、多变量、堆叠、分组、多个子图、折线、曲线直方图)

袁袁袁袁满 2023-09-26 原文

文章目录

专栏导读

🔥🔥本文已收录于《100天精通Python从入门到就业》:本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整教学,从0到100的不断进阶深入,后续还有实战项目,轻松应对面试,专栏订阅地址:https://blog.csdn.net/yuan2019035055/category_11466020.html

  • 优点订阅限时9.9付费专栏进入千人全栈VIP答疑群,作者优先解答机会(代码指导、远程服务),群里大佬众多可以抱团取暖(大厂内推机会)
  • 专栏福利简历指导、招聘内推、每周送实体书、80G全栈学习视频、300本IT电子书:Python、Java、前端、大数据、数据库、算法、爬虫、数据分析、机器学习、面试题库等等

1. 直方图介绍

1)介绍

直方图(Histogram),又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。可以将一组数据中的频率或频数汇总显示在一个图表上,以频率柱的形式表示数据的比例和分布。

特点

  • 更直观的展示数据分布
  • 易于比较数据之间的差异
  • 易于发现数据中的极端值
  • 可以更直观地发现正态分布、非正态分布以及偏态分布

应用场景

  • 分析客户行为、特征分布
  • 分析产品特征、卖点
  • 分析市场份额
  • 分析需求量

2)直方图的五种形态

(1)标准型

标准型直方图的特点是:

  • 区间宽度相等:每个区间的宽度应该相等,这样才能保证直方图的准确性。

  • 矩形高度表示频率或密度:每个矩形的高度应该表示该区间内数据的频率或密度,这样才能反映出数据的分布情况。

  • 相邻矩形相连:相邻的矩形应该相连,这样才能形成连续的直方图。

  • 坐标轴标注清晰:坐标轴应该标注清晰,包括横轴表示数据范围,纵轴表示频率或密度。

(2)孤岛型

在直方图旁边有孤立的小岛出现,当这种情况出现时过程中有异常原因:

(3)双峰型

当直方图中出现了两个峰,这是由于观测值来自两个总体、两个分布的数据混合在一起造成的:

(4)折齿型

当直方图出现凹凸不平的形状,这是由于作图时数据分组太多,测量仪器误差过大或观测数据不准确等造成的,此时应重新收集数据和整理数据:

(5)陡壁型

当直方图像高山的陡壁向一边倾斜时,通常表现在产品质量较差时,为了符合标准的产品,需要进行全数检查,以剔除不合格品:

3)参数说明

在matplotlib中,使用plt.hist()函数可以绘制直方图。该函数的主要参数如下:

plt.hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, color=None, label=None, stacked=False, alpha=None, edgecolor=None, linewidth=None, xticks=None, yticks=None, **kwargs)

常用参数的说明如下:

  • x:需要绘制直方图的数据,可以是一个数组或序列。
  • bins:指定直方图的条形数,或者指定每个条形的边界值。默认值为10。
  • range:指定直方图的范围,即x轴的取值范围。默认值为None,表示使用数据的最大值和最小值作为范围。
  • density:指定是否将直方图归一化。默认值为None,表示不进行归一化。
  • cumulative:指定是否绘制累计直方图。默认值为False。
  • histtype:指定直方图的类型,可以是’bar’、‘barstacked’、‘step’、‘stepfilled’。默认值为’bar’。
  • align:指定直方图条形的对齐方式。默认值为’mid’,表示条形的中心与x轴上的标签对齐。
  • orientation:指定直方图的方向,可以是’horizontal’或’vertical’。默认值为’vertical’。
  • color:指定直方图的颜色。
  • label:指定直方图的标签。
  • alpha:指定直方图的透明度。
  • edgecolor:指定直方图条形边缘的颜色。
  • linewidth:指定直方图条形边缘的宽度。
  • xticks、yticks:指定x轴、y轴上的刻度值。

2. 单变量直方图

单变量直方图用于绘制一个变量的频率分布情况,可以使用plt.hist()函数绘制:

import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl

# 展示中文字体
mpl.rcParams['font.sans-serif'] = ['SimHei'] 

# 生成数据
np.random.seed(0)
x = np.random.randn(1000)

# 绘制直方图
plt.hist(x, bins=20, alpha=0.5, color='steelblue', edgecolor='black')

# 添加标题和坐标轴标签
plt.title('单变量直方图')
plt.xlabel('数据值')
plt.ylabel('频数')

# 显示图形
plt.show()

代码解释

使用numpy.random.randn()生成1000个随机数作为数据。
使用plt.hist()函数绘制直方图,指定bins为20,alpha为0.5,颜色为steelblue,边缘颜色为black。
使用plt.title()、plt.xlabel()和plt.ylabel()添加标题和坐标轴标签。
使用plt.show()显示图形。

运行结果

3. 多变量直方图

多变量直方图用于绘制两个变量的关系,可以使用plt.hist2d()函数绘制:

import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 生成数据
np.random.seed(0)
x = np.random.randn(1000)
y = np.random.randn(1000)

# 绘制直方图
plt.hist2d(x, y, bins=20, cmap='Blues')

# 添加标题和坐标轴标签
plt.title('多变量直方图')
plt.xlabel('x')
plt.ylabel('y')

# 添加颜色条
plt.colorbar()

# 显示图形
plt.show()

代码解释

使用numpy.random.randn()生成1000个随机数作为x和y的数据。
使用plt.hist2d()函数绘制直方图,指定bins为20,颜色映射为Blues。
使用plt.title()、plt.xlabel()和plt.ylabel()添加标题和坐标轴标签。
使用plt.colorbar()添加颜色条。
使用plt.show()显示图形。

运行结果

4. 堆叠直方图

堆叠直方图用于比较两个或多个变量的频率分布情况,可以使用plt.hist()函数结合numpy.histogram()函数绘制:

import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 生成数据
np.random.seed(0)
x1 = np.random.randn(1000)
x2 = np.random.randn(1000) + 1

# 计算直方图数据
bins = np.linspace(-5, 5, 21)
hist1, _ = np.histogram(x1, bins=bins)
hist2, _ = np.histogram(x2, bins=bins)

# 绘制堆叠直方图
plt.hist([x1, x2], bins=bins, stacked=True, alpha=0.5, label=['x1', 'x2'])

# 添加标题和坐标轴标签
plt.title('堆叠直方图')
plt.xlabel('数据值')
plt.ylabel('频数')

# 添加图例
plt.legend()

# 显示图形
plt.show()

代码解释

使用numpy.random.randn()生成1000个随机数作为x1和x2的数据。
使用numpy.linspace()生成21个等距的数作为bins。
使用numpy.histogram()函数分别计算x1和x2的直方图数据。
使用plt.hist()函数绘制堆叠直方图,指定bins为bins,alpha为0.5,标签为'x1'和'x2'。
使用plt.title()、plt.xlabel()和plt.ylabel()添加标题和坐标轴标签。
使用plt.legend()添加图例。
使用plt.show()显示图形。

运行结果

5. 分组直方图

分组直方图用于比较不同组之间的频率分布情况,可以使用plt.hist()函数结合numpy.histogram()函数绘制:

import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 生成数据
np.random.seed(0)
x1 = np.random.randn(1000)
x2 = np.random.randn(1000) + 1

# 计算直方图数据
bins = np.linspace(-5, 5, 21)
hist1, _ = np.histogram(x1, bins=bins)
hist2, _ = np.histogram(x2, bins=bins)

# 绘制分组直方图
width = 0.4
plt.bar(bins[:-1], hist1, width=width, align='edge', alpha=0.5, label='x1')
plt.bar(bins[:-1]+width, hist2, width=width, align='edge', alpha=0.5, label='x2')

# 添加标题和坐标轴标签
plt.title('分组直方图')
plt.xlabel('数据值')
plt.ylabel('频数')

# 添加图例
plt.legend()

# 显示图形
plt.show()

代码解释

使用numpy.random.randn()生成1000个随机数作为x1和x2的数据。
使用numpy.linspace()生成21个等距的数作为bins。
使用numpy.histogram()函数分别计算x1和x2的直方图数据。
使用plt.bar()函数绘制分组直方图,指定宽度为0.4,对齐方式为'edge',标签为'x1'和'x2'。
使用plt.title()、plt.xlabel()和plt.ylabel()添加标题和坐标轴标签。
使用plt.legend()添加图例。
使用plt.show()显示图形。

运行结果

6. 多个子图的直方图

下面是一个示例代码,它使用matplotlib库绘制了一个2x2的子图,每个子图都是一个直方图。

import matplotlib.pyplot as plt
import numpy as np

# 生成随机数据
data1 = np.random.normal(0, 1, 1000)
data2 = np.random.normal(2, 1, 1000)
data3 = np.random.normal(-2, 1, 1000)
data4 = np.random.normal(0, 2, 1000)

# 设置图像大小和分辨率
fig = plt.figure(figsize=(10, 8), dpi=80)

# 绘制第一个子图
ax1 = fig.add_subplot(2, 2, 1)
ax1.hist(data1, bins=30, alpha=0.5, color='blue')
ax1.set_title('Subplot 1')

# 绘制第二个子图
ax2 = fig.add_subplot(2, 2, 2)
ax2.hist(data2, bins=30, alpha=0.5, color='red')
ax2.set_title('Subplot 2')

# 绘制第三个子图
ax3 = fig.add_subplot(2, 2, 3)
ax3.hist(data3, bins=30, alpha=0.5, color='green')
ax3.set_title('Subplot 3')

# 绘制第四个子图
ax4 = fig.add_subplot(2, 2, 4)
ax4.hist(data4, bins=30, alpha=0.5, color='purple')
ax4.set_title('Subplot 4')

# 调整子图之间的距离和位置
plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=0.4, hspace=0.4)

# 显示图像
plt.show()

代码中使用了numpy库生成了4组随机数据,然后使用matplotlib库创建了一个大小为10x8、分辨率为80的图像。接着,使用add_subplot()方法在图像上创建了4个子图,并分别将随机数据绘制成直方图。最后,使用subplots_adjust()方法调整了子图之间的距离和位置,使它们更加美观。最后,使用show()方法显示图像。

运行结果

7. 折线直方图

在直方图中,我们也可以加一个折线图,辅助我们查看数据变化情况

import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 生成随机数据
data  = np.random.normal(0, 1, 1000)

# 创建Axes对象
fig,ax = plt.subplots()

# 绘制直方图
n,bins_num,pat = ax.hist(data,bins=10,alpha=0.5, color='blue') 
 
# 绘制折线图
ax.plot(bins_num[:10],n,marker = 'o',color="yellowgreen",linestyle="--")

# 添加标题和坐标轴标签
plt.title('折线直方图')
plt.xlabel('数据值')
plt.ylabel('频数')

# 添加图例
plt.legend(labels=['频次'])

# 展示图像
plt.show()

代码解释

首先通过pyplot.subplot()创建Axes对象

通过Axes对象调用hist()方法绘制直方图,返回折线图所需要的下x,y数据

然后Axes对象调用plot()绘制折线图

运行结果

8. 正态分布曲线直方图

下面是一个示例代码,它使用matplotlib库绘制了一个曲线拟合直方图

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from scipy.optimize import curve_fit
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 生成随机数据
data = np.random.normal(0, 1, 1000)

# 绘制直方图
n, bins, patches = plt.hist(data, bins=30, density=True, alpha=0.5, color='blue')

# 定义拟合函数
def fit_function(x, mu, std, a):
    return a * norm.pdf(x, mu, std)

# 初始拟合参数
mu, std = norm.fit(data)
a = 1

# 拟合曲线
popt, pcov = curve_fit(fit_function, bins[:-1], n, p0=[mu, std, a])
x = np.linspace(bins[0], bins[-1], 100)
plt.plot(x, fit_function(x, *popt), 'r-', linewidth=2)

# 设置图像标题和坐标轴标签
plt.title('曲线拟合直方图')
plt.xlabel('数据值')
plt.ylabel('频数')

# 显示图像
plt.show()

代码解释

代码中使用了numpy库生成了1000个符合正态分布的随机数据,然后使用matplotlib库的hist()方法将这些数据绘制成直方图,并设置了bins为30,density为True表示绘制的是概率分布直方图,alpha为0.5表示设置透明度为0.5,color为blue表示设置颜色为蓝色。同时,返回了直方图的数值、区间和补丁。

接着,定义了一个拟合函数fit_function,它使用了norm.pdf()方法计算了正态分布的概率密度函数,并乘以一个系数a,用于调整拟合曲线的幅度。然后,使用scipy库的curve_fit()方法拟合了直方图的数据,并生成了100个均匀分布的数据,用于绘制拟合曲线。最后,使用matplotlib库的plot()方法绘制了拟合曲线,并使用title()、xlabel()和ylabel()方法设置了图像的标题和坐标轴标签。

图像中展示了随机数据的曲线拟合情况,蓝色的直方图表示随机数据的分布情况,红色的曲线是拟合曲线。拟合曲线是通过拟合函数fit_function和直方图的数据计算得出的,它可以更好地描述随机数据的分布情况。

运行结果:

9. 核密度曲线直方图

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from sklearn.neighbors import KernelDensity
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 生成随机数据
np.random.seed(123)
data = np.random.normal(loc=0, scale=1, size=1000)

# 计算正态分布概率密度函数的值
x = np.linspace(-4, 4, 100)
pdf = norm.pdf(x)

# 计算核密度估计的值
kde = KernelDensity(kernel='gaussian', bandwidth=0.2).fit(data.reshape(-1, 1))

# 计算正态分布估计的值
log_dens = kde.score_samples(x.reshape(-1, 1))
dens = np.exp(log_dens)

# 绘制直方图和曲线
fig, ax = plt.subplots()
ax.hist(data, bins=30, density=True, alpha=0.5, color='blue')
ax.plot(x, pdf, 'r-', label='正态分布曲线')
ax.plot(x, dens, 'g--', label='核密度曲线')
ax.legend()
plt.show()

代码解释

在这个代码中,我们首先使用numpy生成了一个长度为1000的随机数据,然后使用scipy.stats.norm计算了正态分布的概率密度函数的值,并使用sklearn.neighbors.KernelDensity计算了核密度估计的值。接着,我们使用matplotlib绘制了直方图和两个曲线,其中正态分布曲线的颜色为红色实线,核密度曲线的颜色为绿色虚线。最后,我们使用plt.show()方法显示了图形。

运行结果

正态分布曲线和核密度曲线的区别和应用场景如下

  • 正态分布曲线,也称为高斯分布曲线,是一种连续性分布函数,通常用于描述数据集中度和散布度。正态分布曲线具有钟形对称的形状,其参数由均值和标准差确定。正态分布曲线在统计学中有广泛的应用,例如在假设检验、置信区间估计、回归分析等方面。

  • 核密度曲线则是一种非参数估计方法,用于估计概率密度函数。核密度曲线的形状取决于所选用的核函数,通常使用高斯核函数。核密度曲线可以用于描述数据分布的形状和密度,也可以用于比较两个数据集之间的差异。在数据挖掘、模式识别、图像处理等领域中,核密度估计方法被广泛应用。

  • 正态分布曲线和核密度曲线都可以用于描述数据的分布情况,但在应用场景上有所不同。正态分布曲线通常用于描述连续性变量的分布,例如身高、体重、考试成绩等。而核密度曲线则更适用于描述离散性变量的分布,例如文本中词语出现的频率、图像中像素值的分布等。

有关100天精通Python(可视化篇)——第84天:matplotlib绘制不同种类炫酷直方图参数说明+代码实战(普通、多变量、堆叠、分组、多个子图、折线、曲线直方图)的更多相关文章

  1. ruby - Ruby 中的波形可视化 - 2

    我即将开始一个将录制和编辑音频文件的项目,我正在寻找一个好的库(最好是Ruby,但会考虑Java或.NET以外的任何库)以进行实时可视化波形。有人知道我应该从哪里开始搜索吗? 最佳答案 要流入浏览器的数据量很大。Flash或Flex图表可能是唯一能提高内存效率的解决方案。Javascript图表往往会因大型数据集而崩溃。 关于ruby-Ruby中的波形可视化,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  2. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  3. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  4. ruby-on-rails - ActiveRecord:除非另有说明,否则在保存之前使所有文本字段都调用 strip - 2

    多年来,我在各种网站上遇到过各种问题,用户在字符串和文本字段的开头/结尾放置空格。有时这些会导致格式/布局问题,有时会导致搜索问题(即搜索顺序看起来不对,但实际上并非如此),有时它们实际上会使应用程序崩溃。我认为这会很有用,而不是像我过去所做的那样放入一堆before_save回调,向ActiveRecord添加一些功能以在保存之前自动调用任何字符串/文本字段上的.strip,除非我告诉它不是,例如do_not_strip:field_x,:field_y或类定义顶部的类似内容。在我去弄清楚如何做到这一点之前,有没有人看到更好的解决方案?明确一点,我已经知道我可以做到这一点:befor

  5. ruby - 如何从 Chef 说明书中的库访问当前节点? - 2

    我正在尝试为ChefRecipe编写一个库,以简化一些常见的搜索。例如,我希望能够在cookbook/libraries/library.rb中执行类似的操作,然后从同一Recipe中的Recipe中使用它:moduleExampledefself.search_attribute(attribute_name)returnsearch(:nodes,node[attribute_name])endend问题是,在Chef库文件中,node对象或search函数都不可用。似乎可以使用Chef::Search::Query.new().search(...)进行搜索,但我找不到任何可以访

  6. Unity数据可视化图表插件XCharts3.0发布 - 2

    Unity数据可视化图表插件XCharts3.0发布历时8个多月,业余时间,断断续续,XCharts3.0总算发布了。如果要打个满意度,我给3.0版本来个80分。对于代码框架结构设计的调整改动,基本符合预期,甚是满意。相比之前的1.0和2.0版本,我认为3.0才是一个拿得出手给广大开发者使用的版本。1.0发布的时候,很兴奋,从0.1到1.0,也磨了一年,真的等不及想给大家试用了,还特地写过一篇文章以示庆祝。那个时候,1.0虽然还还不够完善,功能也不够丰富,但它是XCharts的开始,没有1.0,也就没有后面的2.0和3.0。后面的2.0发布,做了很多改进和优化,随着版本迭代,慢慢的发现有不少硬

  7. 你真正了解什么是接口测试么?接口实战一“篇”入魂 - 2

    最近在工作中,看到一些新手测试同学,对接口测试存在很多疑问,甚至包括一些从事软件测试3,5年的同学,在聊到接口时,也是一知半解;今天借着这个机会,对接口测试做个实战教学,顺便总结一下经验,分享给大家。计划拆分成4个模块跟大家做一个分享,(接口测试、接口基础知识、接口自动化、接口进阶)感兴趣的小伙伴记得关注,希望对你的日常工作和求职面试,带来一些帮助。注:文章较长有5000多字,希望小伙伴们认真看完,当然有些内容对小白同学不是太友好,如果你需要详细了解其中的一些概念或者名词,请在文章之后留言,后续我将针对大家的疑问,整理输出一些大家感兴趣的文章。随着开发模式的迭代更新,前后端分离已不是新的概念,

  8. micropython复现经典单片机项目(二)可视化音频 频谱解析(基本搞定) - 2

    本人是音乐爱好者,从小就特别喜欢那个随着音乐跳动的方框效果,就是这个:arduino上一大把对,我忍你很久了,我就想用mpy做,全网没有,行我自己研究。果然兴趣是最好的老师,我之前有篇博客专门讲音频,有兴趣的可以回顾一下。提到可视化频谱,必然绕不开fft,大学学过这玩意,当时一心玩,老师讲的一个字都么听进去,网上教程简略扫了一下,大该就是把时域转频域的工具,我大mpy居然没有fft函数,奶奶的,先放着。音频信息如何收集?第一种傻瓜式的ADC,模拟转数字,原始粗暴,第二种,I2S库,我之前博客有讲过,数据是PCM编码。然后又去学PCM编码,一学豁然开朗,舒服,以代码为例:audio_in=I2S

  9. ruby-on-rails - Ruby On Rails 4.2 的可视化日志查看器 - 2

    我以前在Laravel4上工作过,它有一个很棒的日志查看器工具laravellogviewer查看demo我正在寻找与Rubyonrails4.2非常相似的东西,如果你们知道Rails4.2的任何好的可视化日志记录GEM,请告诉我..从代码我需要记录不同的日志级别,这个工具应该直观地组织我的日志,谢谢.. 最佳答案 这应该可以帮助您入门https://github.com/shadabahmed/logstasher如其所说Thisgemisheavilyinspiredfromlograge,butit'sfocusedonone

  10. FIFO实战学习-同步FIFO/异步FIFO-格雷码 - 2

    目录FIFO一.自定义同步FIFO1.1代码设计1.2Testbech1.3行为仿真***学习位宽计算函数$clog2()***$clog2()系统函数使用,可以不关注***分布式资源或者BLOCKBRAM二.异步FIFO2.1在FIFO判满的时候有两种方式:2.2异步FIFO为什么要使用格雷码2.2.1介绍格雷码2.2.2格雷码在异步FIFO中的应用2.2.2格雷码判满2.4二进制与格雷码之间的转换2.4.1二进制码转换为格雷码的方法2.4.2格雷码转换为二进制码的方法2.3实现框图2.5实现及仿真代码2.6仿真图验证2.7结论FIFO  这篇更多的是记录FIFO学习,参考了众多优秀的文章,

随机推荐