matlab 频率分布直方图_绘制频率分布直方图的三种方法,总结的很用心!

本文介绍了如何使用Python的Matplotlib、Pandas和Seaborn模块绘制频率分布直方图,详细解析了hist函数和distplot函数的参数及用法,并通过深圳疫情年龄数据进行实例展示。

直方图能帮助迅速了解数据的分布形态,将观测数据分组,并以柱状条表示各分组中观测数据的个数。简单而有效的可视化方法,可检测数据是否有问题,也可看出数据是否遵从某种已知分布。

本次案例通过生成深圳市疫情个案数据集中所有患者的年龄参数直方图。

分别使用Matplotlib、Pandas、Seaborn模块可视化Histogram。

其中,Matplotlib和Pandas样式简单,看上去吸引力不大。Seaborn可往单变量直方图上添加很多东西,更美观,pandas可成组生成直方图。

导入库/数据

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import datetime
import time
df=pd.read_excel(r"szdata.xls")
df.head(5)

Matplotlib模块

##注意原始数据集不能存在缺失值,绘制前必须对缺失数据删除或替换,否则无法绘制成功.
##检查年龄是否有缺失
any(df.年龄.isnull()) #False
##删除含有缺失年龄的数据
df.dropna(subset=["年龄"],inplace=True)
##绘制直方图
plt.rcParams["font.sans-serif"]='SimHei'
plt.rcParams['axes.unicode_minus']=False
%config InlineBackend.figure_format='svg'

plt.hist(x=df.年龄,bins=20,
        color="steelblue",
        edgecolor="black")

#添加x轴和y轴标签
plt.xlabel("年龄")
plt.ylabel("病例数")

#添加标题
plt.title("患者年龄分布")

#显示图形
plt.show()

338ef77e03ef334446ce4decd9d6d9bc.png

Pandas模块

#注意直方图上添加核密度图,必须将直方图频数更改为频率,即normed参数设置成True
#直方图
df.年龄.plot(kind="hist",bins=20,color="steelblue",edgecolor="black",normed=True,label="直方图")

#加核密度图
df.年龄.plot(kind="kde",color="red",label="核密度图")

#添加x轴和y轴标签
plt.xlabel("年龄")
plt.ylabel("核密度值")

#添加标题
plt.title("患者年龄分布")

#显示图例
plt.legend()

#显示图形
plt.show()

86342433f5ad75843472f465c40cdf13.png

# pandas.cut() 也同样是一个方便的方法,用来将数据进行强制的分箱
# 将一系列数值分成若干份
#cut()方法,参数bin指明切分区间,左开右闭区间。
import numpy as np
from pandas import Series,DataFrame
ages=list(df.年龄)
bins=[0,29,39,49,50,np.inf]  #范围
labels=["少年","青年组","中青年组","中年组","中老年组"]
groups=pd.cut(ages,bins=bins,labels=labels)
data=groups.value_counts()
#qcut()方法,不需要事先指明切分区间,只需要指明切分个数。
# pd.qcut(ages,6).value_counts()
df1=DataFrame(data,columns=["病例数"])

plt.subplot(1,1,1)
x=labels
y=df1["病例数"].values
plt.bar(x,y,width=0.5,align="center")
plt.title("深圳市患者按年龄分组",loc="center")
for a,b in zip(x,y):   
     plt.text(a,b,b,ha="center",va="bottom",fontsize=12)#添加数据标签
plt.ylim(0,140)
plt.xlabel('分组',labelpad=10)
plt.ylabel('病例数')
plt.savefig(r"bar.jpg")

# 条形图
# 将柱形图x轴和y轴调换,barh方法
# plt.barh(y,width,height,align,color,edgecolor)

f9a6e833f98a3b6eaa87566f71f7b390.png

pandas也提供了一个方便的.value_counts() 方法,用来计算一个非空值的直方图,并将之转变成一个pandas的series结构:df.年龄.value_counts()

Seaborn模块

# 上面表达了所有患者的年龄分布,如果按性别分组,
# 研究不同性别下年龄分布的差异,该如何实现叻?针对这个问题,推荐使用Seaborn模块中的distplot函数
#取出男性年龄
Age_Male=df.年龄[df.性别=="男性"]
#取出女性年龄
Age_Female=df.年龄[df.性别=="女性"]

#绘制男女患者年龄的直方图
sns.distplot(Age_Male,bins=20,kde=False,hist_kws={"color":"steelblue"},label="男性")

#绘制男女患者年龄的直方图
sns.distplot(Age_Female,bins=20,kde=False,hist_kws={"color":"purple"},label="女性")
#添加标题
plt.title("不同性别患者年龄分布直方图")

#显示图例
plt.legend()

#显示图形
plt.show()

ee50b7e6a9666eaec47e69315ce0c1a3.png

#绘制核密度函图
#绘制男女患者年龄的直方图
sns.distplot(Age_Male,hist=False,kde_kws={"color":"red","linestyle":"-"},norm_hist=True,label="男性")

#绘制男女患者年龄的直方图
sns.distplot(Age_Female,hist=False,kde_kws={"color":"blue","linestyle":"--"},norm_hist=True,label="女性")
#添加标题
plt.title("不同性别患者年龄核密度图")

#显示图例
plt.legend()

#显示图形
plt.show()

d1b5feb4f615d879f9b8e7eae769aa69.png

Python实现histogram方法

#生成直方图
# count_elements() 返回了一个字典,字典里的键值对:所有数值出现的频率次数。
# hist[i] = hist.get(i, 0) + 1 实现了每个数值次数的累积
a = tuple(df.年龄)
def count_elements(seq) -> dict:
    hist = {}
    for i in seq:
        hist[i] = hist.get(i, 0) + 1
    return hist
counted = count_elements(a)
counted
#或通过collection.Counter类库实现
# from collections import Counter
# counted = Counter(a)
# counted

#利用输出格式format来实现直方图的展示
def histogram(seq) -> None:
    counted = count_elements(seq)
    for k in sorted(counted):
        print('{0:5d} {1}'.format(k, '@' * counted[k]))
histogram(a)

dab36d4d888d42afed204075e1da5646.png

附函数语法及参数含义

Matplotlib模块中hist函数

Plt.hist(x,bins=10,range=None,normed=False,weights=None,cumulative=False,bottom=None,histtype=’bar’,align=’mid’,orientation=’vertical’,rwidth=None,log=False,color=None,edgecolor=None,label=None,stacked=False)1)、x:指定要绘制直方图的数据。2)、bins:指定直方图条形的个数。3)、range:指定直方图数据的上下界,默认包含绘图数据的最大值和最小值。4)、normed:是否将直方图的频数转换成频率。5)、weights:该参数可为每一个数据节点设置权重。6)、cumulative:是否需要计算累积频数或频率。7)、bottom:可以为直方图的每个条形添加基准线,默认为0.8)、histtype:指定直方图的类型,默认bar,其他八日stacked、step和stepfilled。9)、align:设置条形边界的对齐方式,默认mid,另外left和right。10)、orientation:设置直方图的摆放方向,默认vertical垂直方向。11)、rwidth:设置直方图条形的宽度。12)、log:是否需要对绘图数据进行log变换。13)、color:设置直方图的填充色。14)、edgecolor:设置直方图边框色。15)、label:设置直方图的标签,可通过legend展示图例。16)、stacked:当有多个数据时,是否需要将直方图呈堆叠摆放,默认水平摆放。

Seaborn模块

Sns.distplot(x,bins=None,hist=True,kde=True,rug=False,fit=None,hist_kws=None,kde_kws=None,rug_kws=None,fit_kws=None,color=None,vertical=False,norm_hist=False,axlabel=None,label=None,ax=None)

1)、x:指定绘图数据,可以是序列、一维数组或列表。2)、bins:指定直方图条形的个数。3)、hist:bool类型的参数,是否绘制直方图,默认True。4)、kde:bool类型的参数,是否绘制核密度图,默认True。5)、rug:bool类型的参数,是否绘制须图,(如果数据比较密集,该参数比较有用)默认False。6)、fit:指定一个随机分布对象,需调用scipy模块中随机分布函数,用于绘制随机分布概率密度曲线。7)、hist_kws:以字典形式传递直方图的其他修饰属性,如填充色、边框色、宽度等。8)、kde_kws:以字典形式传递核密度图的其他修饰属性,如线的颜色、线的类型等。

9)、rug_kws:以字典形式传递须图的其他修饰属性,如线的颜色、线的宽度等。10)、fit_kws:以字典形式传递须图的其他修饰属性,如线的颜色、线的宽度等。11)、color:指定图颜色,除了随机分布曲线的颜色。12)、vertical:是否将图形垂直显示,默认True。13)、norm_hist:是否将频数更改为频率,默认False。14)、axlabel:用于显示轴标签。15)、label:指定图形图例,需要结合plt.legend()一起使用。16)、ax:指定子图的位置。

Python新手成长之路案例集锦,长按关注:

7152c72da4f4ed4fd5c081e775edb143.png

<think>我们被要求使用MATLAB绘制频率分布直方图。根据引用内容,我们可以使用histogram函数(较新的版本推荐)或hist函数(旧版本)来绘制。 引用[1]中使用了histogram函数,引用[2]中使用了hist函数。考虑到histogram是MATLAB推荐使用的(hist在后续版本可能被移除),我们优先使用histogram。 步骤: 1. 准备数据:生成或导入需要绘制直方图的数据。 2. 确定分组:可以指定分组的边界(bin edges)或分组数量(bin width)。 3. 计算频率:使用histogram函数可以直接得到频数,然后可以转换为频率(即每个分组的频数除以总样本数)。 4. 绘制直方图:使用histogram函数绘制,并可以设置颜色、透明度等属性。 5. 如果需要,还可以添加累积频率曲线(如引用[1]所示)。 下面我们按照引用[1]中的示例代码进行说明,并生成一个示例。 注意:引用[1]中同时绘制频率分布直方图和累积频率曲线,并且使用了双纵坐标。 我们将按照以下步骤编写代码: - 生成随机数据(这里用正态分布随机数为例) - 使用histogram函数绘制直方图(设置'binwidth'等参数) - 计算累积频率(使用cumsum函数) - 在同一个图中,右侧纵轴绘制累积频率曲线 但是,请注意:histogram函数返回的对象可以直接用来获取每个bin的频数,然后我们可以计算频率和累积频率。 具体代码步骤: 1. 生成数据:例如,生成10000个正态分布的随机数。 2. 创建直方图对象:使用histogram函数,并指定bin宽度(例如0.1),同时获取频数(Counts)和bin边界(BinEdges)。 3. 计算频率:频数除以总数。 4. 计算累积频率:使用cumsum函数对频率进行累加。 5. 绘制直方图:使用histogram函数绘制,并设置左侧纵轴为频数(或频率,这里示例是频数)。 6. 在同一图中,使用yyaxis right切换到右侧纵轴,绘制累积频率曲线(使用stairs或plot,注意横坐标取bin边界,但累积频率的点数比bin边界少一个,所以需要调整。或者我们可以使用bin的中心位置,或者使用bin的边界,但累积频率绘制通常是在每个bin的右边界处绘制,从0开始,到最后一个bin的右边界处累积频率为1)。 然而,累积频率曲线(或称经验分布函数)的绘制通常使用阶梯图(stairs),横坐标取每个bin的右边界,纵坐标为到该bin为止的累积频率。 但是,引用[1]中使用了bin的中心位置绘制累积频率曲线,这也可以,但更常见的是使用bin的边界。 这里我们按照引用[1]的方法:使用bin的中心位置(即每个bin的中间值)来绘制累积频率曲线。 注意:histogram函数返回的bin中心可以通过`bin_centers = h.BinEdges(1:end-1) + h.BinWidth/2;`得到,但这样比较麻烦。我们可以使用histogram的'BinEdges'参数,然后自己计算中心点。 另一种方法:在调用histogram时指定'BinEdges',然后中心点可以取为`(BinEdges(1:end-1)+BinEdges(2:end))/2`。 但是,引用[1]中使用了预先指定的x(中心点)来计算hist(旧函数),而我们使用histogram时,可以这样: edges = -4:0.1:4; % 指定bin边界 h = histogram(data, edges); counts = h.Values; % 每个bin的频数 binCenters = (edges(1:end-1) + edges(2:end))/2; % 每个bin的中心位置 然后计算频率:freq = counts / sum(counts); 累积频率:cumFreq = cumsum(freq); 然后绘制累积频率曲线时,横坐标用binCenters,纵坐标用cumFreq。 但是,累积频率曲线应该从0开始,然后到最后一个bin结束为1。所以我们可以在累积频率数组前面加一个0,然后横坐标从第一个边界开始,这样用阶梯图绘制更合适。不过引用[1]中直接使用中心点绘制折线图。 这里我们按照引用[1]的方法绘制折线图(plot),即使用中心点和累积频率值。 下面我们给出一个完整的示例代码,并添加注释。 注意:引用[1]中使用了两个纵坐标,左侧为频数,右侧为频率(累积频率)。我们这里左侧显示频数,右侧显示累积频率(0~1)。 代码示例: ```matlab % 生成随机数据 rng(0); % 设置随机种子,使结果可重复 data = randn(10000,1); % 生成10000个标准正态分布的随机数 % 指定bin边界 binEdges = -4:0.1:4; % 从-4到4,步长0.1 % 创建直方图 figure; hold on; yyaxis left; % 激活左侧纵轴 h = histogram(data, binEdges, 'FaceColor', [1 0.27 0.0], 'EdgeColor', [1 1 1], 'FaceAlpha', 0.5); xlabel('Variable'); ylabel('Counts'); xlim([-4,4]); % 设置x轴范围 set(gca, 'FontSize', 12); % 计算累积频率 counts = h.Values; % 获取每个bin的频数 freq = counts / sum(counts); % 频率 cumFreq = cumsum(freq); % 累积频率 % 计算每个bin的中心位置(用于绘制累积频率曲线) binCenters = (binEdges(1:end-1) + binEdges(2:end)) / 2; % 绘制累积频率曲线 yyaxis right; % 激活右侧纵轴 plot(binCenters, cumFreq, 'k-', 'LineWidth', 2); ylabel('Cumulative Frequency'); ylim([0,1]); % 设置累积频率范围为0到1 set(gca, 'FontSize', 12); % 添加网格、标题等 grid on; title('频率分布直方图与累积频率曲线'); box on; % 调整图形窗口大小(可选) set(gcf, 'Position', [100, 100, 800, 500]); ``` 注意:上述代码中,我们使用了`yyaxis`来创建双纵坐标图。左侧是直方图的频数,右侧是累积频率曲线。 另外,我们指定了bin边界为-4到4,步长0.1。这样每个bin的宽度为0.1。 如果不想指定边界,也可以使用'BinWidth'参数,例如: h = histogram(data, 'BinWidth', 0.1, 'FaceColor', ...); 但是这样bin边界可能不是从-4开始,我们可以通过设置'BinLimits'来限制范围。 或者,我们可以使用自动划分,然后调整x轴范围。 但是为了精确控制,我们推荐指定bin边界。 另外,引用[2]中介绍了hist函数的使用,但histogram是更现代的函数,建议使用histogram。 以上代码在MATLAB R2016a及以上版本中运行(因为yyaxis在R2016a引入)。 如果使用的是更早的版本,可以使用subplot或者plotyy函数(不推荐,因为plotyy将被移除)。 现在,我们根据要求,生成相关问题。 §§相关问题§§ 1. MATLAB中histogram函数与hist函数有什么区别? 2. 如何调整直方图的bin宽度和bin边界? 3. 除了正态分布,如何用MATLAB绘制其他分布(如泊松分布)的频率分布直方图? 4. 如何在同一图中绘制多个数据集的频率分布直方图?</think>### MATLAB 绘制频率分布直方图方法MATLAB绘制频率分布直方图主要使用 `histogram` 函数(推荐)或 `hist` 函数(旧版)。以下是详细步骤和示例代码: --- #### **方法 1:使用 `histogram` 函数(推荐)** ```matlab %% 生成随机数据(10000个正态分布随机数) data = randn(10000,1); %% 绘制频率分布直方图 figure; hold on; % 左侧纵轴:频数直方图 yyaxis left; h = histogram(data, 'BinWidth', 0.1, ... % 指定分组宽度 'FaceColor', [1 0.27 0.0], ... % 柱状图颜色 'EdgeColor', 'white', ... % 边缘颜色 'FaceAlpha', 0.5); % 透明度 xlabel('变量值'); ylabel('频数'); xlim([-4 4]); % 横轴范围 % 右侧纵轴:累积频率曲线 yyaxis right; [freq, edges] = histcounts(data, 'BinWidth', 0.1); % 获取频数 cumFreq = cumsum(freq) / sum(freq); % 计算累积频率 binCenters = edges(1:end-1) + 0.05; % 计算分组中心点 plot(binCenters, cumFreq, 'k-', 'LineWidth', 2); % 绘制曲线 ylabel('累积频率'); ylim([0 1]); %% 图形美化 set(gca, 'FontSize', 12, 'Box', 'on'); title('频率分布直方图与累积频率曲线'); grid on; ``` **关键参数说明**: - `BinWidth`:分组宽度(此处为0.1) - `FaceColor`/`EdgeColor`:控制柱状图颜色和边缘 - `yyaxis`:双纵坐标(左侧频数,右侧累积频率) - `cumsum(freq)/sum(freq)`:计算累积频率[^1] --- #### **方法 2:使用 `hist` 函数(旧版)** ```matlab %% 生成数据并指定分组中点 data = randn(10000,1); binCenters = -3.9:0.1:3.9; % 分组中点(-3.9, -3.8,...,3.9) %% 计算频数和频率 counts = hist(data, binCenters); % 频数 freq = counts / sum(counts); % 频率 cumFreq = cumsum(freq); % 累积频率 %% 绘制图形 figure; bar(binCenters, counts); % 频数直方图 xlabel('变量值'); ylabel('频数'); hold on; plot(binCenters, cumFreq*max(counts), 'r-', 'LineWidth', 2); % 叠加累积频率曲线 ``` **注意**:此方法需手动缩放累积频率曲线以适应纵轴[^2]。 --- #### **关键区别** | 函数 | 特点 | |--------------|----------------------------------------------------------------------| | `histogram` | 直接支持频率/概率模式,可返回分组边界,推荐使用 | | `hist` | 返回分组频数,需手动计算频率,未来版本可能移除 | > 💡 **提示**:通过 `histogram` 的 `'Normalization'` 参数可直接绘制**概率密度直方图**: > ```matlab > histogram(data, 'BinWidth', 0.1, 'Normalization', 'pdf'); > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值