情境引入

我们在做机器学习相关项目时,常常会分析数据集的样本分布,而这就需要用到直方图的绘制。

在Python中可以很容易地调用matplotlib.pyplothist函数来绘制直方图。不过,该函数参数不少,有几个绘图的小细节也需要注意。

首先,我们假定现在有个联邦学习的项目情景。我们有一个样本个数为15的图片数据集,样本标签有4个,分别为cat, dog, car, ship。这个数据集已经被不均衡地划分到4个任务节点(client)上,如像下面表示:

N_CLIENTS = 3
num_cls, classes = 4, ['cat', 'dog', 'car', 'ship']
train_labels = [0, 3, 2, 0, 3, 2, 1, 0, 3, 3, 1, 0, 3, 2, 2] #数据集的标签列表 client_idcs = [slice(0, 4), slice(4, 11), slice(11, 15)]
# 数据集样本在client上的划分情况

我们需要可视化样本在任务节点的分布情况。我们第一次可能会写出如下代码:

import matplotlib.pyplot as plt
import numpy as np plt.figure(figsize=(5,3))
plt.hist([train_labels[idc]for idc in client_idcs], stacked=False,
bins=num_cls,
label=["Client {}".format(i) for i in range(N_CLIENTS)]) plt.xticks(np.arange(num_cls), classes)
plt.legend()
plt.show()

此时的可视化结果如下:

这时我们会发现,我们x轴上的标签和上方的bar(每个图像类别对应的3个bar合称为1个bin)并没有对齐,而这时剧需要我们调整bins这个参数。

bins 参数

在讲述bins参数之前我们先来熟悉一下hist绘图中bin和bar的含义。下面是它们的诠释图:

这里\(x_1\)、\(x_2\)是x轴对象,在hist中,默认x轴第一个对象对应刻度为0,第2个对象刻度为1,依次类图。在这个诠释图上,bin(原意为垃圾箱)就是指每个x轴对象所占优的矩形绘图区域,bar(原意为块)就是指每个矩形绘图区域中的条形。 如上图所示,x轴第一个对象对应的bin区间为[-0.5, 0.5),第2个对象对应的bin区域为[0.5, 1)(注意,hist规定一定是左闭又开)。每个对象的bin区域内都有3个bar。

通过查阅matplotlib文档,我们知道了bins参数的解释如下:

bins: int or sequence or str, default: rcParams["hist.bins"] (default: 10)

If bins is an integer, it defines the number of equal-width bins in the range.

If bins is a sequence, it defines the bin edges, including the left edge of the first bin and the right edge of the last bin; in this case, bins may be unequally spaced. All but the last (righthand-most) bin is half-open. In other words, if bins is:

[1, 2, 3, 4]

then the first bin is [1, 2) (including 1, but excluding 2) and the second [2, 3). The last bin, however, is [3, 4], which includes 4.

If bins is a string, it is one of the binning strategies supported by numpy.histogram_bin_edges: 'auto', 'fd', 'doane', 'scott', 'stone', 'rice', 'sturges', or 'sqrt'.

我来概括一下,也就是说如果bins是个数字,那么它设置的是bin的个数,也就是沿着x轴划分多少个独立的绘图区域。我们这里有四个图像类别,故需要设置4个绘图区域,每个区域相对于x轴刻度的偏移采取默认设置。

不过,如果我们要设置每个区域的位置偏移,我们就需要将bins设置为一个序列。

bins序列的刻度要参照hist函数中的x坐标刻度来设置,本任务中4个分类类别对应的x轴刻度分别为[0, 1, 2, 3] 。如果我们将序列设置为[0, 1, 2, 3, 4]就表示第一个绘图区域对应的区间是[1, 2),第2个绘图区域对应的位置是[1, 2),第三个绘图区域对应的位置是[2, 3),依次类推。

就大众审美而言,我们想让每个区域的中心和对应x轴刻度对齐,这第一个区域的区间为[-0.5, 0.5),第二个区域的区间为[0.5, 1.5),依次类推。则最终的bins序列为[-0.5, 0.5, 1.5, 2.5, 3.5]。于是,我们将hist函数修改如下:

plt.hist([train_labels[idc]for idc in client_idcs], stacked=False,
bins=np.arange(-0.5, 4, 1),
label=["Client {}".format(i) for i in range(N_CLIENTS)])

这样,每个划分区域和对应x轴的刻度就对齐了:

stacked参数

有时x轴的项目多了,每个x轴的对象都要设置3个bar对绘图空间无疑是一个巨大的占用。在这个情况下我们如何压缩空间的使用呢?这个时候参数stacked就派上了用场,我们将参数stacked设置为True:

plt.hist([train_labels[idc]for idc in client_idcs],stacked=True
bins=np.arange(-0.5, 4, 1),
label=["Client {}".format(i) for i in range(N_CLIENTS)])

可以看到每个x轴对象的bar都“叠加”起来了:

不过,新的问题又出来了,这样每x轴对象的bar之间完全没有距离了,显得十分“拥挤”,我们可否修改bins参数以设置区域bin之间的间距呢?答案是不行,因为我们前面提到过,bins参数中只能将区域设置为连续排布的。

换一个思路,我们设置每个bin内的bar和bin边界之间的间距。此时,我们需要修改r_width参数。

rwidth 参数

我们看文档中对rwidth参数的解释:

rwidth float or None, default: None

The relative width of the bars as a fraction of the bin width. If None, automatically compute the width.

Ignored if histtype is 'step' or 'stepfilled'.

翻译一下,rwidth用于设置每个bin中的bar相对bin的大小。这里我们不妨修改为0.5:

plt.hist([train_labels[idc]for idc in client_idcs],stacked=True,
bins=np.arange(-0.5, 4, 1), rwidth=0.5,
label=["Client {}".format(i) for i in range(N_CLIENTS)])

修改之后的图表如下:

可以看到每个x轴元素内的bar正好占对应bin的宽度的二分之一。

引用

Matplotlib直方图绘制技巧的更多相关文章

  1. matplotlib 直方图绘制详解

    n, bins, patches = plt.hist(datasets, bins, normed=False, facecolor=None, alpha=None) 函数说明 用于绘制多个数据集 ...

  2. 利用pandas读取Excel表格,用matplotlib.pyplot绘制直方图、折线图、饼图

    利用pandas读取Excel表格,用matplotlib.pyplot绘制直方图.折线图.饼图 数据: 折线图代码: import  pandas  as pdimport  matplotlib. ...

  3. Python的工具包[2] -> matplotlib图像绘制 -> matplotlib 库及使用总结

    matplotlib图像绘制 / matplotlib image description  目录 关于matplotlib matplotlib库 补充内容 Figure和AxesSubplot的生 ...

  4. Matplotlib 图形绘制

    章节 Matplotlib 安装 Matplotlib 入门 Matplotlib 基本概念 Matplotlib 图形绘制 Matplotlib 多个图形 Matplotlib 其他类型图形 Mat ...

  5. Android 4.0的图形硬件加速及绘制技巧

    转:http://zuiniuwang.blog.51cto.com/3709988/721798 从Android 3.0开始,Android 2D的绘制流程就设计为能够更好地支持硬件加速.使用GP ...

  6. matplotlib如何绘制直方图、条形图和饼图

    1 绘制直方图: import matplotlib.pyplot as plt import numpy as np import matplotlib def hist1(): # 设置matpl ...

  7. Oracle索引梳理系列(十)- 直方图使用技巧及analyze table操作对直方图统计的影响(谨慎使用)

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  8. 【python】pandas & matplotlib 数据处理 绘制曲面图

    Python matplotlib模块,是扩展的MATLAB的一个绘图工具库,它可以绘制各种图形 建议安装 Anaconda后使用 ,集成了很多第三库,基本满足大家的需求,下载地址,对应选择pytho ...

  9. 数据分析——Matplotlib图形绘制

    创建画布或子图 函数名称 函数作用 plt.figure 创建一个空白画布,可以指定画布大小,像素. figure.add_subplot 创建并选中子图,可以指定子图的行数,列数,与选中图片编号. ...

随机推荐

  1. Mobile phones(poj1195)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 18453   Accepted: 8542 De ...

  2. mod4最优路径问题(转载)

    原文链接:https://blog.csdn.net/ACdreamers/article/details/18501855 mod4最优路径问题 如下图: 从1到4找出一条路径,要求路径的总长度mo ...

  3. Java初学者作业——为某超市设计管理系统,需要在控制台展示系统菜单,菜单之间可以完成跳转。

    返回本章节 返回作业目录 需求说明: 为某超市设计管理系统,需要在控制台展示系统菜单,菜单之间可以完成跳转. 实现思路: 定义mainMenu方法,用于显示主菜单. 主菜单主要负责显示4个选项,分别是 ...

  4. 编写Java程序,使用List集合和Map集合输出 市和区

    如图: 代码: import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java ...

  5. 初识python 之 爬虫:爬取某网站的壁纸图片

    用到的主要知识点:requests.get 获取网页HTMLetree.HTML 使用lxml解析器解析网页xpath 使用xpath获取网页标签信息.图片地址request.urlretrieve ...

  6. [ SQLAlchemy ] 自我引用型的多对多关系(Self-Referential Many-to-Many Relationship)理解

    参考: https://www.jianshu.com/p/2c6c76f94b88 https://madmalls.com/blog/post/followers-and-followeds/ 实 ...

  7. Servlet简单实现开发部署过程

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6512008683445027331/ 主要是从下面三个步骤实现我们的预期: (1)构建开发环境: (2)开发Ser ...

  8. vue3.0+vite+ts项目搭建-postcss-pxtorem 实现移动自适应(五)

    这里不考虑大屏,所以不做amfe-flexible的配置 首先是安装依赖 yarn add postcss-loader postcss-pxtorem -D yarn add autoprefixe ...

  9. 经典定长指令-修改EIP

    1.0x70~0x7F EIP无法像通用寄存器那样用mov来修改,只能通过类似于jz,JNB,JNE JBE,call等的跳转指令来进行修改 条件跳转,后跟一个字节立即数的偏移(有符号),共两个字节. ...

  10. BeanUtils.copyProperties 选择性赋值字段

    BeanUtils.copyProperties 在字段赋值上有强大的功能,如果有两个的类,如果需要将相同的字段赋值,就可以直接赋制.而不需要每个字段都需要一个一个赋制. BeanUtils.copy ...