【问题标题】:Python Matplotlib - "weighted" boxplotPython Matplotlib - “加权”箱线图
【发布时间】:2020-12-09 13:48:54
【问题描述】:

我正在尝试创建一个带有指定数字的箱线图,该数字表示该值在数据中出现的次数。

我有什么:

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 个盒子的一些合并列表的长度将超过 500。我有大约 20 个这样的盒子。有没有更有效的方法?

提前致谢!

【问题讨论】:

    标签: python numpy matplotlib plot graph


    【解决方案1】:

    首先,当前版本的 numpy 给出了弃用警告,因为列表列表只有在每个子列表具有相同数量的元素时才能转换为 numpy 数组。将这样的列表列表转换为 numpy 格式只是保留列表格式的列表。

    还要注意np.append() 是一个缓慢的操作,在每一步都会创建数组的完整副本,因此应谨慎使用。参见例如How can I append to a numpy array without reassigning the result to a new variable?.

    要重复列表中的每个元素,可以通过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])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-15
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 2016-06-22
      相关资源
      最近更新 更多