在Python中使用Counter()构建直方图?
我在另一个问题上看到,我可以使用在Python中使用Counter()构建直方图?,python,histogram,Python,Histogram,我在另一个问题上看到,我可以使用Counter()来计算一组字符串中出现的次数。所以如果我有['A','B','A','C','A','A','A']我得到计数器({'A':3,'B':1,'C':1})。但是现在,我如何使用这些信息来构建柱状图呢?例如,对于您的数据,可能最好使用条形图而不是柱状图。查看此代码: from collections import Counter import numpy as np import matplotlib.pyplot as plt labels,
Counter()
来计算一组字符串中出现的次数。所以如果我有['A','B','A','C','A','A','A']
我得到计数器({'A':3,'B':1,'C':1})
。但是现在,我如何使用这些信息来构建柱状图呢?例如,对于您的数据,可能最好使用条形图而不是柱状图。查看此代码:
from collections import Counter
import numpy as np
import matplotlib.pyplot as plt
labels, values = zip(*Counter(['A','B','A','C','A','A']).items())
indexes = np.arange(len(labels))
width = 1
plt.bar(indexes, values, width)
plt.xticks(indexes + width * 0.5, labels)
plt.show()
结果:
您可以使用以下方法编写一些非常简洁的代码: 导致:
根据Igonato的回答,我创建了一个带有类“plot”的助手模块“plot” 它有两个函数hist()和barchart(),这两个函数显示了Igonato的方法,以及直接使用matplotlib hist功能,这可能是本问题最初的意图 该方法允许添加具有给定字体大小的标题和标签,并以1的勾号频率显示y轴。您还可以更改模式,使其保存具有给定标题的图表。为方便起见,有关闭和调试选项 python单元测试\u Plot.py
'''
Created on 2020-07-05
@author: wf
'''
import unittest
from ptp.plot import Plot
class TestPlot(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def testPlot(self):
''' test a plot based on a Counter '''
valueList=['A','B','A','C','A','A'];
plot=Plot(valueList,"barchart example",xlabel="Char",ylabel="frequency")
plot.barchart(mode='save')
plot.title="histogram example"
plot.debug=True
plot.hist(mode='save')
pass
if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
'''
Created on 2020-07-05
@author: wf
'''
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np
import os
class Plot(object):
'''
create Plot based on counters
see https://stackoverflow.com/questions/19198920/using-counter-in-python-to-build-histogram
'''
def __init__(self, valueList,title,xlabel=None,ylabel=None,fontsize=12,plotdir=None,debug=False):
'''
Constructor
'''
self.counter=Counter(valueList)
self.valueList=valueList
self.title=title
self.xlabel=xlabel
self.ylabel=ylabel
self.fontsize=fontsize
self.debug=debug
path=os.path.dirname(__file__)
if plotdir is not None:
self.plotdir=plotdir
else:
self.plotdir=path+"/../plots/"
os.makedirs(self.plotdir,exist_ok=True)
def titleMe(self):
plt.title(self.title, fontsize=self.fontsize)
if self.xlabel is not None:
plt.xlabel(self.xlabel)
if self.ylabel is not None:
plt.ylabel(self.ylabel)
def showMe(self,mode='show',close=True):
''' show me in the given mode '''
if mode=="show":
plt.show()
else:
plt.savefig(self.plotdir+self.title+".jpg")
if close:
plt.close()
def barchart(self,mode='show'):
''' barchart based histogram for the given counter '''
labels, values = zip(*self.counter.items())
indexes = np.arange(len(labels))
width = 1
self.titleMe()
plt.bar(indexes, values, width)
plt.xticks(indexes + width * 0.5, labels)
plt.yticks(np.arange(1,max(values)+1,step=1))
self.showMe(mode)
def showDebug(self):
print(" value list: ",self.valueList)
print("counter items: ",self.counter.items())
print("counter values: ",self.counter.values())
print("counter keys: ",self.counter.keys())
def hist(self,mode="show"):
''' create histogram for the given counter '''
if self.debug:
self.showDebug()
self.titleMe()
# see https://stackoverflow.com/a/2162045/1497139
plt.hist(self.valueList,bins=len(self.counter.keys()))
self.showMe(mode)
pass
结果:
调试输出:
value list: ['A', 'B', 'A', 'C', 'A', 'A']
counter items: dict_items([('A', 4), ('B', 1), ('C', 1)])
counter values: dict_values([4, 1, 1])
counter keys: dict_keys(['A', 'B', 'C'])
plot.py
'''
Created on 2020-07-05
@author: wf
'''
import unittest
from ptp.plot import Plot
class TestPlot(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def testPlot(self):
''' test a plot based on a Counter '''
valueList=['A','B','A','C','A','A'];
plot=Plot(valueList,"barchart example",xlabel="Char",ylabel="frequency")
plot.barchart(mode='save')
plot.title="histogram example"
plot.debug=True
plot.hist(mode='save')
pass
if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
'''
Created on 2020-07-05
@author: wf
'''
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np
import os
class Plot(object):
'''
create Plot based on counters
see https://stackoverflow.com/questions/19198920/using-counter-in-python-to-build-histogram
'''
def __init__(self, valueList,title,xlabel=None,ylabel=None,fontsize=12,plotdir=None,debug=False):
'''
Constructor
'''
self.counter=Counter(valueList)
self.valueList=valueList
self.title=title
self.xlabel=xlabel
self.ylabel=ylabel
self.fontsize=fontsize
self.debug=debug
path=os.path.dirname(__file__)
if plotdir is not None:
self.plotdir=plotdir
else:
self.plotdir=path+"/../plots/"
os.makedirs(self.plotdir,exist_ok=True)
def titleMe(self):
plt.title(self.title, fontsize=self.fontsize)
if self.xlabel is not None:
plt.xlabel(self.xlabel)
if self.ylabel is not None:
plt.ylabel(self.ylabel)
def showMe(self,mode='show',close=True):
''' show me in the given mode '''
if mode=="show":
plt.show()
else:
plt.savefig(self.plotdir+self.title+".jpg")
if close:
plt.close()
def barchart(self,mode='show'):
''' barchart based histogram for the given counter '''
labels, values = zip(*self.counter.items())
indexes = np.arange(len(labels))
width = 1
self.titleMe()
plt.bar(indexes, values, width)
plt.xticks(indexes + width * 0.5, labels)
plt.yticks(np.arange(1,max(values)+1,step=1))
self.showMe(mode)
def showDebug(self):
print(" value list: ",self.valueList)
print("counter items: ",self.counter.items())
print("counter values: ",self.counter.values())
print("counter keys: ",self.counter.keys())
def hist(self,mode="show"):
''' create histogram for the given counter '''
if self.debug:
self.showDebug()
self.titleMe()
# see https://stackoverflow.com/a/2162045/1497139
plt.hist(self.valueList,bins=len(self.counter.keys()))
self.showMe(mode)
pass
如果你想建立一个直方图,我建议你使用numpy和MATPLOTLIB,从技术上看,这是一个直方图——它有分量(字母)和频率(出现的次数)。你是在问如何把它做成条形图吗?我是在问如何提取每个字母的信息。Igonato回答了我的问题。您可以在对象上始终使用
帮助
或dir
功能,以找出可用于该对象的方法和属性。如果OP的数据最适合直方图,该怎么办?我知道游戏已经很晚了,但我想更新你的答案,以应用于直方图示例(但我还不知道怎么做)。这将回答问题的标题。@ThomasMatthew从技术上讲,这是一个直方图。“条形图代替柱状图”更多的是指使用matplotlib.pyplot.bar
代替matplotlib.pyplot.hist
。我相信bar
与Counter
配合得更好(这是OP想要的),这也是一个3年前的问题changed@ThomasMatthew你是怎么到的,你在找什么?它在谷歌的得分高吗?什么疑问?如果它显示在python计数器matplotlib之外的其他内容上,那么编辑回答搜索的“从计数器构建直方图”可能是有意义的,它是Google搜索结果#1。这和OP的问题几乎是同一个标题。对于搜索该查询的所有人来说,更新是值得的,这可能是对这个问题的高百分比的看法。更新(添加)直方图示例后,您可能会获得更多的投票和收藏夹,但OP特别询问了有关计数器的问题。要回答这个问题,您应该演示如何从计数器
转到系列
,除非有另一种类型更适合字典。不清楚您的解决方案是否真的适用于此——这只是一个条形图的示例。一个简洁的实现!