通过对 x 轴值进行排序,在同一图中制作 3 个直方图

Make 3 histograms in the same figure by ordering x-axis values

l 想绘制共享同一 x 轴的三个向量的直方图,即 classes。 类(101 个字符串值)是一组标签

classes={'playingguitar', 'billiards', 'boxingboxingspeedbag', 'applylipstick', 'playingsitar', 'fieldhockeypenalty', 'blowingcandles', 'longjump', 'playingdhol', 'biking', 'playingpiano', 'handstandwalking', 'playingcello', 'ropeclimbing', 'hulahoop', 'cricketshot', 'punch', 'pushups', 'floorgymnastics', 'jumpingjack', 'lunges', 'golfswing', 'bandmarching', 'skiing', 'playingtabla', 'archery', 'breaststroke', 'unevenbars', 'playingviolin', 'babycrawling', 'moppingfloor', 'bowling', 'knitting', 'rockclimbingindoor', 'shavingbeard', 'writingonboard', 'shotput', 'stillrings', 'drumming', 'applyeyemakeup', 'cuttinginkitchen', 'pizzatossing', 'soccerpenalty', 'bodyweightsquats', 'taichi', 'benchpress', 'trampolinejumping', 'playingdaf', 'pullups', 'pommelhorse', 'jumprope', 'headmassage', 'horserace', 'skijet', 'surfing', 'basketballdunk', 'polevault', 'brushingteeth', 'salsaspin', 'frontcrawl', 'horseriding', 'typing', 'throwdiscus', 'nunchucks', 'diving', 'balancebeam', 'highjump', 'volleyballspiking', 'icedancing', 'cricketbowling', 'rafting', 'yoyo', 'walkingwithdog', 'swing', 'hammering', 'mixing', 'wallpushups', 'parallelbars', 'skateboarding', 'skydiving', 'jugglingballs', 'soccerjuggling', 'kayaking', 'cleanandjerk', 'tennisswing', 'playingflute', 'javelinthrow', 'haircut', 'blowdryhair', 'cliffdiving', 'frisbeecatch', 'boxingspeedbag', 'handstandpushups', 'militaryparade', 'hammerthrow', 'rowing', 'basketball', 'baseballpitch', 'tabletennisshot', 'fencing', 'sumowrestling'}
len(classes)=101

labels2labels2_testlabels2_full_train中,我们有每个class的出现次数,顺序不同:

from collections import Counter
import numpy as np
import matplotlib.pyplot as plt
import pylab
labels2, values2 = zip(*Counter(train2).items())
labels2_test, values_test2 = zip(*Counter(test).items())
labels2_full_train, values2_full_train = zip(*Counter(full_train).items())

l 想绘制一个图,使 x 轴表示 classes,y 轴表示 values2, values_test2, values2_full_train

中每个 class 的出现次数

我试过什么?

pylab.rcParams['figure.figsize'] = (30, 10)
fig1, ax1 = plt.subplots()
ax1.tick_params(rotation=90)
ax1.plot(labels2, values2, label='train classes')
ax1.plot(labels2_test, values_test2, label='test classes')
ax1.plot(labels2_full_train,  values2_full_train, label='test classes')
ax1.set_xlabel("classes",rotation='vertical')
ax1.set_ylabel("number of examples")
ax1.set_title("data distibution")
ax1.legend(loc='best')
fig1.show()

但是我得到如下信息:

因为 labels2labels2_testlabels2_full_train

中的排序方式不同
labels2, values2 = zip(*Counter(train2).items())
labels2_test, values_test2 = zip(*Counter(test).items())
labels2_full_train, values2_full_train = zip(*Counter(full_train).items())

那么我怎样才能以相同的顺序获得 labels2labels2_testlabels2_full_train(例如 classes 中定义的)?

例如

labels2=['rafting', 'punch', 'applyeyemakeup',...]
values2=[78, 112, 106,...]
labels2_test=['typing', 'surfing', 'cricketbowling',..]
values_test2=[46, 38, 39,...]
labels2_full_train=['archery', 'benchpress', 'brushingteeth',...]
values2_full_train=[1046, 1043, 1065,...]

谢谢

问题

因为 matplotlib 显示在轴上排序的分类变量,所以您需要在绘图之前按字母顺序对列表进行排序。因此,让我们创建一个完整且可验证的示例:

from collections import Counter

list1 = list("ABADEAABEDDAEDBBBBBD") # letters A, B, D, E
list2 = list("AABAEEDCCFFFEDABEEC")  # all letters A-F

items1, counts1 = zip(*sorted(Counter(list1).items()))
items2, counts2 = zip(*sorted(Counter(list2).items()))


import matplotlib.pyplot as plt
plt.plot(items1, counts1, label="list1")
plt.plot(items2, counts2, label="list2")
plt.legend()
plt.show()

请注意,第一个列表包含所有可能项目的子集。输出如下所示:

所以不幸的是,虽然列表本身是排序的,但该图显示了一些奇怪的行为,因为轴在末尾显示 CF

解决方案

解决这个问题的方法是让轴事先知道 所有 可能要绘制的项目。我们可以例如在轴上绘制所有项目的不可见图,

import matplotlib.pyplot as plt

plt.plot(items1+items2, [5]*len(items1+items2), visible=False)

plt.plot(items1, counts1, "o-", label="list1")
plt.plot(items2, counts2, "o-", label="list2")
plt.legend()
plt.show()