前回
前回はデータの分類をやったので今回はグラフの作成
3.グラフの作成
こういったグラフにするためには、「階級数」だけリストを作成し、それらの要素数は「最大の階級の値」する。そのうえで、各リストを最後尾から「■」で埋めて、最後に縦軸を合成すればいい。つまり、階級数が10、最大の階級の値が10であれば、10個の空白の要素を持つ10個のリストを用意すればよい。
#sep_listは階級(横軸)
#separatedは元データを階級別に分けたもの
longest = 0
for i in separated:
if len(i) > longest:
longest = len(i)
y = longest + 1
x = len(sep_list)
graph = [[' ']*x for _ in range(y)]
sep_list = list(map(lambda x: (map(lambda y: str(y),x)), sep_list))
#sep_listは[int, int]の形なのでstrに変換
graph[y-1] = list(map(lambda x:'~'.join(x), sep_list))
#グラフのリスト末尾に軸を追加
for i in range(x):
volume = len(separated[i])
for k in range(volume,0,-1): #後ろから■で埋めてく
graph[y-1-k][i] = "■"
最後にグラフの縦軸を作成する。
まず、グラフの縦軸の数字を含むリスト用意する。縦軸は、グラフを含むリストの一次元目の要素数~1までをとる。ここでは次のステップの都合上0まで含むリストを「要素数」、「要素数-1」... 「0」といった形で作成する。
その後、このリストをグラフリストの一次元目の要素(リスト)の先頭に入れる形で結合する。
最後にグラフリストの[0][0]を半角スペースに置換する。
#graphはグラフを格納しているリスト
num = [[i] for i in range(len(graph)-1,-1,-1)]
for i in range(len(graph)):
graph[i] = num[i] + graph[i]
self.graph[len(graph)-1][0] = ' '
最後にこれまでのコードをまとめてクラス化するとこう
class histogram:
"""docstring-
data_array -> ヒストグラムにしたいデータ(一次元リスト)
sep -> ヒストグラムの階級
drawメソッドで実行
output_to_csvメソッドでワーキングディレクトリにcsv書き出し
"""
def __init__(self, data_array, sep):
self.data = data_array
self.s = min(data_array)
self.e = max(data_array)
self.sep = sep
self.separated = []
self.sep_list = []
def draw(self):
self.distribute_data()
self.select_list()
self.draw_a_histogram()
self.draw_vertical_axis()
def draw_a_histogram(self):
longest = 0
for i in self.separated:
if len(i) > longest:
longest = len(i)
y = longest + 1
x = len(self.sep_list)
self.graph = [[' ']*x for _ in range(y)]
self.sep_list = list(map(lambda x: (map(lambda y: str(y),x)), self.sep_list))
self.graph[y-1] = list(map(lambda x:'~'.join(x), self.sep_list))
for i in range(x):
volume = len(self.separated[i])
for k in range(volume,0,-1):
self.graph[y-1-k][i] = "■"
def distribute_data(self):
n = (self.e - self.s+1)//self.sep
if (self.e - self.s +1)%self.sep != 0:
n += 1
self.separated = [[] for _ in range(n)]
for i in range(n):
if i == 0:
self.sep_list.append([self.s, self.s + self.sep -1])
else:
previous = self.sep_list[i-1][1]
nxt = previous + self.sep
if nxt >= self.e:
nxt = self.e
if previous + 1 == nxt:
self.sep_list.append([previous+1])
else:
self.sep_list.append([previous+1, nxt])
def select_list(self):
for i in self.data:
counter = (i - self.s) // self.sep
self.separated[counter].append(i)
def draw_vertical_axis(self):
num = [[i] for i in range(len(self.graph)-1,-1,-1)]
for i in range(len(self.graph)):
self.graph[i] = num[i] + self.graph[i]
self.graph[len(self.graph)-1][0] = ' '
def output_to_csv(self):
import csv
with open("./histogram.csv",encoding = "utf-8",newline='',mode="w") as f:
writer = csv.writer(f)
writer.writerows(self.graph)