python - Python Matplotlib - “加权”箱线图
问题描述
我正在尝试创建一个具有指定数字的箱线图,该数字表示该值在数据中出现的次数。
我有的:
import numpy as np
import matplotlib.pyplot as plt
data = np.array([[[0, 1, 2, 3], [31, 84, 2, 1]], [[0, 1, 2], [17, 104, 21]], [[0, 1, 2, 3, 4], [17, 106, 61, 3, 1]]])
plt.boxplot([data[0][0], data[1][0], data[2][0]])
输出:
我想要的是:
- 第一个框:数据“0”出现 31 次,“1”出现 84 次等(所有框都相同)
- 这将改变四分位数范围,中线等
我知道我可以做类似的事情:(对于每个盒子)
merged_list_box1 = np.array([])
np.append(merged_list_box1, data[0][1][0]*31)
np.append(merged_list_box1, data[0][1][1]*84)
.
.
.
但是由于我拥有的数据集,1个盒子的一些merged_list的长度将超过500。我有大约20个这样的盒子。有没有更有效的方法?
提前致谢!
解决方案
首先,当前版本的 numpy 给出了弃用警告,因为如果每个子列表具有相同数量的元素,列表列表只能转换为 numpy 数组。将这样的列表列表转换为 numpy 格式只会保留列表格式的列表。
另请注意,这np.append()
是一个缓慢的操作,在每一步创建数组的完整副本,应谨慎使用。请参阅例如如何在不将结果重新分配给新变量的情况下附加到 numpy 数组?.
要重复列表中的每个元素,可以通过 来完成第二个列表中给出的次数np.repeat()
。生成的具有 500 个元素的 numpy 数组不是问题。因此,代码可能如下所示:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
data = np.array([[[0, 1, 2, 3], [31, 84, 2, 1]], [[0, 1, 2], [17, 104, 21]], [[0, 1, 2, 3, 4], [17, 106, 61, 3, 1]]])
# or, better, just data = [[[0, 1, 2, 3], [31, 84, 2, 1]], [[0, 1, 2], [17, 104, 21]], [[0, 1, 2, 3, 4], [17, 106, 61, 3, 1]]]
plt.boxplot([np.repeat(d[0], d[1]) for d in data])
plt.gca().yaxis.set_major_locator(MaxNLocator(integer=True))
plt.show()
在这个例子中,第二个“盒子”看起来像一条线,因为第一个和第三个四分位数都等于1
。由于所有输入值都是整数,因此示例代码强制刻度为整数。
假设所有第一个子列表只是从零开始的数字序列,则可以稍微简化数据。
data = [[31, 84, 2, 1], [17, 104, 21], [17, 106, 61, 3, 1]]
plt.boxplot([np.repeat(np.arange(len(d)), d) for d in data])
推荐阅读
- api - 如何创建一个 kdb rest api
- c - 为什么tasklet_action()函数中会调用BUG?
- mongodb - 不同的结构类型切片作为函数的参数
- javascript - 在 react 和 node.js 应用程序中,styles.css 并未仅应用于一页
- javascript - JavaScript xPath
- java - 无法从给定代码访问类错误?
- xml - 在 Spark 中爆炸复杂的嵌套 XML
- firefox - Tampermonkey (Firefox) 用户脚本存储位置
- javascript - 使用 vanilla js 进行表单验证
- haskell - 如何防止指数运算符(^)的默认实现