Matplotlib:使用来自numpy数组的数据和组/子组标签列表的分组箱图

时间:2015-04-01 16:53:40

标签: arrays numpy matplotlib nested boxplot

我是Matplotlib / Python的新手,我正在尝试制作一个与Joe Kington的优秀示例非常相似的分组箱图:

how to make a grouped boxplot graph in matplotlib

我想根据自己的要求修改Joe的例子。

对于我下面的演示数据,我有5个人,每个人在3个不同的任务中都有4次尝试(=“尝试”:'第一','第二','第三','第四')(=“任务“:'A','B','C')。

我希望能够:

1)将我的数据输入为一系列2D numpy数组,每个任务一个数组如图所示,每个数组由嵌套在4次连续尝试中的5个人的得分组成。

2)使用字符串标记绘图的共享x轴上的任务和尝试,分别保存为列表“tasklist”和“attemptlist”中的顺序项。

3)概括解决方案,为任意数量的个人和任意数量的任务制作适当的图表,每个任务都需要多次重复尝试。

编辑: 2015年4月2日:

唯一突出的问题是,当使用.keys()方法时,Python列表将自己组装成非连续顺序的看似反直觉的方式;因此我的任务列表一直以“A,C,B”而不是“A,B,C”出现。 解决方法是导入和创建有序字典。这对我来说是全新的,但这似乎要求我的任务列表中的项目名称要像Joe在他的示例中所做的那样被声明两次 - 一次将任务与相应的数据矩阵相关联,并且一次将项目名称关联到带有相应顺序数字键的有序字典...

想知道:是否存在一种方法(类似于常规字典的.keys()方法),它将迭代我的数据矩阵,按所示顺序(“A,B,C”)创建一个有序字典,要求我两次输入我的任务列表的详细信息?

非常感谢

戴夫

import matplotlib.pyplot as plt
import numpy as np

data = {}
data ['A'] = np.array([[1,2,3,4,9],[2,3,4,4,4],[3,4,4,5,5],[5,6,6,7,7,7]])
data ['B'] = np.array([[2,3,4,4,5],[3,4,5,6,10],[4,5,6,6,7],[5,6,7,7,8]])
data ['C'] = np.array([[4,5,6,6,10],[6,7,8,8,8],[7,8,9,9,10],[2,10,11,11,12]])

tasklist = data.keys() #  list of labels for tasks 'A' to 'C' (each containing 4 attempts labelled '1st' to '4th')
attemptlist = ['1st','2nd','3rd','4th'] # list of labels for attempts 1 to 4 within each task

fig, axes = plt.subplots(ncols= len(tasklist), sharey=True)
fig.subplots_adjust(wspace=0)

for ax,task in zip(axes,tasklist):
    ax.boxplot([data[task][attemptlist.index(attempt)] for attempt in attemptlist],showfliers=False)
    ax.set(xticklabels=attemptlist, xlabel=task)
plt.show()

1 个答案:

答案 0 :(得分:1)

@cphlewis:非常感谢:根据您的建议,重新编写了代码格式为元组列表(任务,数据)的代码,现在可以控制绘制任务的顺序。

MWE在下面发布,以防这对其他任何人都有帮助。

import matplotlib.pyplot as plt

data = [[('A'),[[1,2,3,4,9],[2,3,4,4,4],[3,4,4,5,5],[5,6,6,7,7,7]]],
    [('B'),[[2,3,4,4,5],[3,4,5,6,10],[4,5,6,6,7],[5,6,7,7,8]]],
     [('C'),[[4,5,6,6,10],[6,7,8,8,8],[7,8,9,9,10],[2,10,11,11,12]]]
     ]
attemptlist = ['1st','2nd','3rd','4th'] 
fig, axes = plt.subplots(ncols= len(data), sharey=True)
fig.subplots_adjust(wspace=0)

for ax,d in zip(axes,data):     
    ax.boxplot([d[1][attemptlist.index(attempt)] for attempt in attemptlist],showfliers=False)
    ax.set(xticklabels=attemptlist, xlabel=d[0])
plt.show()