根据 Igonato 的回答,我创建了一个带有“Plot”类的辅助模块“plot”。
它有两个函数 hist() 和 barchart() 两个显示 Igonato 的方法以及直接使用 matplotlib hist 功能,这可能是问题中最初的打算。
该方法允许添加具有给定字体大小的标题和标签,并以 1 的刻度频率显示 y 轴。您还可以更改模式以保存具有给定标题的图表。为方便起见,有关闭和调试选项。
python 单元测试 test_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()
结果:
调试输出:
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 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