白话解读matplotlib用法-在柱子上添加数据
前情提要
大家好,我是W
前言:在上一篇文中我们学了直方图怎么用,并且,在组数比较小的时候,可能我们需要标注一下柱子的高度。所以接下来我们的学习在直方图中标注出柱子的高度。
补充matplotlib的通用函数
-
在画布上添加文字
plt.text(x=100, y=100, s='text', rotation=90) # x=:表示在画布上的x坐标 # y=:表示在画布上的y坐标 # s=:表示需要展示的文本 # rotation=:表示文本的旋转角度
在直方图中标注出柱子的高度
经过上面的plt.text()
的学习试用,我们应该知道需要在直方图上添加数据就要试用这个函数。
首先我们需要了解plt.hist的返回值
我们先看一下官方文档
Returns
-------
n : array or list of arrays
The values of the histogram bins. See *density* and *weights* for a
description of the possible semantics. If input *x* is an array,
then this is an array of length *nbins*. If input is a sequence of
arrays ``[data1, data2,..]``, then this is a list of arrays with
the values of the histograms for each of the arrays in the same
order. The dtype of the array *n* (or of its element arrays) will
always be float even if no weighting or normalization is used.
bins : array
The edges of the bins. Length nbins + 1 (nbins left edges and right
edge of last bin). Always a single array even when multiple data
sets are passed in.
patches : list or list of lists
Silent list of individual patches used to create the histogram
or list of such list if multiple input datasets.
文字太长了,我也懒得翻了,而且总的来说就是根据不同的传入参数(x=),返回不同的结果。
我直接贴出来我的数据返回的结果:
rects = plt.hist(x=total_list, bins=bins, edgecolor='black')
print(rects)
结果:
(array([1.390e+02, 5.910e+02, 1.556e+03, 2.444e+03, 2.748e+03, 2.453e+03,
1.879e+03, 1.413e+03, 1.031e+03, 6.940e+02, 4.910e+02, 4.150e+02,
3.090e+02, 2.290e+02, 1.940e+02, 1.360e+02, 1.120e+02, 1.070e+02,
5.900e+01, 8.600e+01, 4.500e+01, 2.700e+01, 5.800e+01, 1.700e+01,
3.500e+01, 2.400e+01, 1.300e+01, 2.100e+01, 1.000e+01, 1.900e+01,
..........
0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
0.000e+00, 1.000e+00]), array([ 6, 26, 46, 66, 86, 106, 126, 146, 166, 186, 206,
226, 246, 266, 286, 306, 326, 346, 366, 386, 406, 426,
446, 466, 486, 506, 526, 546, 566, 586, 606, 626, 646,
666, 686, 706, 726, 746, 766, 786, 806, 826, 846, 866,
.....
2866, 2886, 2906, 2926, 2946, 2966, 2986, 3006, 3026, 3046, 3066,
4186, 4206, 4226, 4246, 4266, 4286, 4306, 4326, 4346, 4366, 4386,
4406, 4426, 4446, 4466, 4486, 4506, 4526, 4546, 4566, 4586, 4606]), <a list of 230 Patch objects>)
所以当我传入一个列表时,他会给我返回根据bins间隔统计出来的柱子的高度和我的bins列表。两个列表装在一个元组里,所以我们需要从中取出数据。
实例讲解(代码不可复制直接试用)
首先,要事先说明这个数据是不可以直接复制使用的,因为我使用的是本地的文件数据集,但是使用方法很简单,所以在使用的时候只需要替换成自己的数据集就可以了。
import matplotlib.pyplot as plt
import pandas as pd
plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文
plt.rcParams['axes.unicode_minus'] = False # 显示负号
# pandas加载数据集
df = pd.read_csv("..\\..\\doc\\processed_data\\cd_lianjia-v2_ed.csv")
# 获得需要展示的数据列表
total_list = df["总价"]
# 确定柱子的宽度 也就是区间
width = 20
# bins列表 从数据集的最小值,到最大值,间隔width
bins = [i for i in range(int(min(total_list)), int(max(total_list)) + width, width)]
# 打开画布
fig = plt.figure(figsize=(20, 8), dpi=120)
# 返回我的total_list根据bins统计出来的数据,我传入的bins
rects = plt.hist(x=total_list, bins=bins, edgecolor='black')
# 声明一个列表装每个柱子的高度
bar_num = []
# rects[0] 取出柱子的高度,需要转成int类型
for i in rects[0]:
bar_num.append(int(i))
print(bar_num) # 每个柱子的高度
print(bar_num.index(2444)) # 通过列表的内容确定列表的中内容的索引
print(bins[bar_num.index(2444)])
# 这个循环把列表中的所有数据一次次的贴到画布上
for i in bar_num:
plt.text(x=bins[bar_num.index(i)] - 5, y=i + 22, s=str(i), rotation=90)
plt.xticks(ticks=bins, rotation=90)
plt.show()
效果图如下:
作为一张图来说做的并不好,因为数据比较紧密,x轴刻度都重叠了。但是作为将数据贴如画布来说是成功的,我们看一下更大的图。
综上,我们需要从rects = plt.hist()
取得直方图分组的高度,然后通过循环遍历,把数据一一定位然后通过plt.text()
贴到画布上。