这次的博客停更了很长时间,第一个原因是因为工作的原因,没有多余的时间来一边看视频,一边来写博客、第二个原因是我想对我之前停些时间用来给我之间的知识进行一次的总结、其中还有一个最大的原因是我前几天在写爬虫的时候看见别人写完的爬虫数据用可视化的形式展现出来,所以我就试着模仿了一下,没想到python在这一方面的效果怪好,然后我就又胡思乱想了,我能不能靠我现在的知识来写一个自动图表工具,说干就干,因为这是我第一次独自写一个项目,我又又要保证用到的知识点不超过我的知识范围,所以说整个过程可以称的是惨不忍睹…
程序思路:
我自己选中一个csv文件然后程序输出第一行表头我来选择使用哪中图表?使用几行数据?程序根据我选的来生成图表
第一次
第一次我 的想法很简单我想在一个py文件中,刚开始的时候没有感觉,但是到后面的时候发现我有时候需要在不同的地方导入相同的变量和函数,代码一多,在加上我编程范式又不规范,啊 !那感觉是真难受,最后我就又放弃了。。。。
第一次失败。。。。。。。。。。。。。
第二次
第二次我忽然想到了我之前写爬虫的时候通过在别的py文件中写入数据通过impor函数可以在另外一个函数进行导入,然后我想我可以用一个主py文件进行操控,其他的例如导入数据 ,对数据的解析、绘制图形等功能可以集中到另外的几个py文件中,这样我就又可以省下很多代码了,这次的过程很顺利 ,我把每一种可视化图表类型都分别写到不同的py文件中,但是在写的过程中又发现了一些问题 就是例如折线图和条形图来说 他们都只需要填入x、y两个参数就可以了 我却在每个py文件中都进行了一次导入数据,和过滤数据的操作者就又增加了很多的重复代码。
第二次失败。。。。。。。。。。。。。
第三次
也是我现在使用的一种格式就是 我把构建图表的功能单独放到一个py文件中,又把每一种表放到不同的类中,过滤数据的功能单独过滤到一个py文件中,这样做的好处就是我在以后如果需要新增一个图表类型,我就可以直接在图表的py文件中新建一个图表类就行了,然后在我创建的主py文件中进行导入中,数据过滤也一样,这里的主py文件 只做到调用各个类的作用并不起其他的作用
到我现在为止 我也只使用了matplotlib numpy csv datetime collections 这几个库
现在的情况就是整体的代码大概写完了 其他的就剩下了对代码的优化和其他功能的添加,下面是现在的代码 ,之后的几篇可能都是对这个项目进行修改和更新
主函数
import csv
import matplotlib.pyplot as plt
import ai_menu.get_data as number_data
from ai_menu.menu import bar_menu # 条形图
from ai_menu.menu import pie_menu # 饼图
from ai_menu.menu import plots_menu # 折线图
plt.rcParams["font.family"] = 'Arial Unicode MS'
class ai_menu():
def __init__(self,flie_name):
self.flie_name=flie_name
def ride_headers(self):
'''返回csv文件的表头'''
try:
with open('{}.csv'.format(self.flie_name),'r')as f:
ride=csv.reader(f)
for i in ride:
break
return i
except FileNotFoundError:
print('找不到指定文件')
return ''
def op_menu(self):
hreaders=self.ride_headers()
print(hreaders)
print('''图表代码
1,折线图
2,条形图
3,饼图
4,直方图''')
menu=input('请选择要使用的图表>>>')
if menu=='2':
'''使用折线图'''
op_number=input('请输入想使用几行数据>>>')
if op_number=='2':
print('''数据选择类型
1:设置列表数量进行排序
2:根据列表索引进行排序
3:根据数据范围进行排序(目前只支持:整数)
4:根据时间范围进行排序(需要传入完整的年月日)''')
list_type=int(input('请选择数据选择类型>>>'))
try:
if list_type==1:
data=number_data.get_two_line_data.get_two_number_data(self.flie_name)
line=number_data.get_two_line_data.lists_number(data[0])
bar_menu.two_plt(line[0],line[1],data[1],data[2],self.flie_name)
elif list_type==2:
data=number_data.get_two_line_data.get_two_number_data(self.flie_name)
line=number_data.get_two_line_data.op_list_number(data[0])
bar_menu.two_plt(line[0],line[1],data[1],data[2],self.flie_name)
elif list_type==3:
data=number_data.get_two_line_data.get_two_number_data(self.flie_name)
line=number_data.get_two_line_data.scope_of_data(data[0])
bar_menu.two_plt(line[0],line[1],data[1],data[2],self.flie_name)
elif list_type==4:
print('''x轴显示方式
1:日期作为x轴
2:其他内容作为x轴''')
op_numbers=input('请选择x轴显示方式>>>>')
if op_numbers=='1':
data = number_data.get_two_line_data.get_two_number_data(self.flie_name)
line = number_data.get_two_line_data.scope_of_data_time(data[0])
bar_menu.two_plt(line[0], line[1], data[1], data[2], self.flie_name)
else:
data=number_data.get_two_line_data_time.get_time_name_data(self.flie_name)
line=number_data.get_two_line_data_time.scope_of_data_time_tag(data[0],data[1])
bar_menu.two_plt(line[0],line[1],data[2],data[3],self.flie_name)
else:
print('超过最大索引值')
except TypeError as e:
print('格式错误,不能构建图表。')
pass
elif op_number=='3':
print('''数据选择类型
1:设置列表数量进行排序
2:根据列表索引进行排序
3:根据数据范围进行排序(目前只支持:整数)
4:根据时间范围进行排序(需要传入完整的年月日)''')
list_type = int(input('请选择数据选择类型>>>'))
try:
if list_type==1:
data=number_data.get_three_line_data.get_three_number_data(self.flie_name)
line=number_data.get_three_line_data.list_number(data[0],data[1])
bar_menu.three_bar(line[0],line[1],line[2],data[2],data[3],data[4],self.flie_name)
elif list_type==2:
data = number_data.get_three_line_data.get_three_number_data(self.flie_name)
line = number_data.get_three_line_data.op_list_number(data[0], data[1])
bar_menu.three_bar(line[0], line[1], line[2], data[2], data[3], data[4], self.flie_name)
elif list_type==3:
data = number_data.get_three_line_data.get_three_number_data(self.flie_name)
line = number_data.get_three_line_data.scope_of_data(data[0], data[1])
bar_menu.three_bar(line[0], line[1], line[2], data[2], data[3], data[4], self.flie_name)
elif list_type==4:
print('''x轴显示方式
1:日期作为x轴
2:其他内容作为x轴''')
op_numbers = input('请选择x轴显示方式>>>>')
if op_numbers == '1':
data = number_data.get_three_line_data.get_three_number_data(self.flie_name)
line = number_data.get_three_line_data.scope_of_data_time(data[0], data[1])
bar_menu.three_bar(line[0], line[1], line[2], data[2], data[3], data[4], self.flie_name)
else:
data=number_data.get_three_line_data_time.get_time_name_data(self.flie_name)
line=number_data.get_three_line_data_time.scope_of_data_time_tag(data[0],data[1],data[2])
bar_menu.three_bar(line[0],line[1],line[2],data[3],data[4],data[5],self.flie_name)
else:
print('超过最大索引值')
except Exception as e:
print('格式错误,不能构建图表')
pass
elif menu=='1': #使用折线图
op_number = int(input('请输入想使用几行数据>>>'))
if op_number == 2:
print('''数据选择类型
1:设置列表数量进行排序
2:根据列表索引进行排序
3:根据数据范围进行排序(目前只支持:整数)
4:根据时间范围进行排序(需要传入完整的年月日)''')
list_type = int(input('请选择数据选择类型>>>'))
try:
if list_type == 1:
data = number_data.get_two_line_data.get_two_number_data(self.flie_name)
line = number_data.get_two_line_data.lists_number(data[0])
plots_menu.two_plt(line[0],line[1],data[1],data[2],self.flie_name)
elif list_type == 2:
data = number_data.get_two_line_data.get_two_number_data(self.flie_name)
line = number_data.get_two_line_data.op_list_number(data[0])
plots_menu.two_plt(line[0],line[1],data[1],data[2],self.flie_name)
elif list_type == 3:
data = number_data.get_two_line_data.get_two_number_data(self.flie_name)
line = number_data.get_two_line_data.scope_of_data(data[0])
plots_menu.two_plt(line[0],line[1],data[1],data[2],self.flie_name)
elif list_type == 4:
print('''x轴显示方式
1:日期作为x轴
2:其他内容作为x轴''')
op_numbers = input('请选择x轴显示方式>>>>')
if op_numbers == '1':
data = number_data.get_two_line_data.get_two_number_data(self.flie_name)
line = number_data.get_two_line_data.scope_of_data_time(data[0])
plots_menu.two_plt(line[0], line[1], data[1], data[2], self.flie_name)
else:
data = number_data.get_two_line_data_time.get_time_name_data(self.flie_name)
line = number_data.get_two_line_data_time.scope_of_data_time_tag(data[0], data[1])
plots_menu.two_plt(line[0], line[1], data[2], data[3], self.flie_name)
else:
print('超过最大索引值')
except TypeError as e:
print('格式错误,不能构建图表。')
pass
elif op_number==3:
'''输入3行数据'''
print('''数据选择类型
1:设置列表数量进行排序
2:根据列表索引进行排序
3:根据数据范围进行排序(目前只支持:整数)
4:根据时间范围进行排序(需要传入完整的年月日)''')
list_type = int(input('请选择数据选择类型>>>'))
if list_type == 1:
data = number_data.get_three_line_data.get_three_number_data(self.flie_name)
line = number_data.get_three_line_data.list_number(data[0], data[1])
plots_menu.three_plt(line[0], line[1], line[2], data[2], data[3], data[4], self.flie_name)
elif list_type == 3:
data = number_data.get_three_line_data.get_three_number_data(self.flie_name)
line = number_data.get_three_line_data.op_list_number(data[0], data[1])
plots_menu.three_plt(line[0], line[1], line[2], data[2], data[3], data[4], self.flie_name)
elif list_type == 2:
data = number_data.get_three_line_data.get_three_number_data(self.flie_name)
line = number_data.get_three_line_data.scope_of_data(data[0], data[1])
plots_menu.three_plt(line[0], line[1], line[2], data[2], data[3], data[4], self.flie_name)
elif list_type == 4:
print('''x轴显示方式
1:日期作为x轴
2:其他内容作为x轴''')
op_numbers = input('请选择x轴显示方式>>>>')
if op_numbers == '1':
data = number_data.get_three_line_data.get_three_number_data(self.flie_name)
line = number_data.get_three_line_data.scope_of_data_time(data[0], data[1])
plots_menu.three_plt(line[0], line[1], line[2], data[2], data[3], data[4], self.flie_name)
else:
data = number_data.get_two_line_data_time.get_time_name_data(self.flie_name)
line = number_data.get_two_line_data_time.scope_of_data_time_tag(data[0], data[1])
plots_menu.three_plt(line[0], line[1], data[2], data[3], self.flie_name)
elif menu=='3':
'''使用饼图'''
line=pie_menu.get_menu(self.flie_name)
pie_menu.plt_menu(line[0],line[1],line[2])
else:
pass
def run(self):
self.op_menu()
def main():
flie=input('请输入打开文件名称:')
data=ai_menu(flie)
data.run()
if __name__ == '__main__':
main()
数据获取和处理
import csv
import datetime
'''以后如果新增加所需数据行数了只需要在这里添加对应的类就可以'''
class get_two_line_data(object):#取两个数据
#---------------------------获取整体数据----------------------------------
def get_two_number_data(flie):
'''首先获得两个行对应的xy值'''
X_name=input('请选择X列名称>>>>')
Y_name=input('请选择Y列名称>>>>')
with open('{}.csv'.format(flie), 'r')as f:
ride = csv.DictReader(f)
data={}
for i in ride:
data.update({i[X_name]:i[Y_name]})
return data,X_name,Y_name
#---------------------------对数据再次进行分类返回----------------------------------
def lists_number(data):
'''根据设置范围返回数据'''
data_keys=data.keys() # 获取字典中的键
x_list=[i for i in data_keys] # 根据字典中的键作为x列
# x_list.sort(reverse=True) # 对字典进行正序排列
list_number=int(input('请输入数据数量界限>>>>'))
if list_number>len(x_list):
try:
y_list=[float(data[i]) for i in x_list] # 根据x的键来查询字典中对应值
return x_list,y_list
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_list] # 根据x的键来查询字典中对应值
return x_list, y_list
except ValueError as e:
y_list = [float(data[i].strip('%'))*100.0 for i in x_list] # 根据x的键来查询字典中对应值
return x_list, y_list
else:
try:
y_list=[float(data[i]) for i in x_list[:list_number]]
return x_list[:list_number],y_list
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_list[:list_number]] # 根据x的键来查询字典中对应值
return x_list[:list_number], y_list
except ValueError as e:
y_list = [float(data[i].strip('%')) / 100.0 for i in x_list[:list_number]] # 根据x的键来查询字典中对应值
return x_list[:list_number], y_list
def op_list_number(data):
data_keys=data.keys()
x_list = [i for i in data_keys]
star_number=int(input('数据开始>>>>'))
end_number=int(input('数据结束>>>>'))
try:
y_list = [float(data[i]) for i in x_list[star_number-1:end_number]]
return x_list[star_number-1:end_number], y_list
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_list[star_number-1:end_number]] # 根据x的键来查询字典中对应值
return x_list[star_number-1:end_number], y_list
except ValueError as e:
y_list = [float(data[i].strip('%')) / 100.0 for i in x_list[star_number-1:end_number]] # 根据x的键来查询字典中对应值
return x_list[star_number-1:end_number], y_list
def scope_of_data(data):
'''根据数据大小进行排列'''
data_keys = data.keys()
x_list = [i for i in data_keys]
greater=int(input('请输入大于某个数>>>>'))
less=int(input('请输入小于某个数>>>>'))
x_lists=[]
for i in x_list:
if less>int(i)>greater:
x_lists.append(i)
else:
pass
try:
y_list = [float(data[i]) for i in x_lists]
return x_lists, y_list
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_lists] # 根据x的键来查询字典中对应值
return x_lists, y_list
except ValueError as e:
y_list = [float(data[i].strip('%')) / 100.0 for i in
x_lists] # 根据x的键来查询字典中对应值
return x_lists, y_list
def scope_of_data_time(data):
'''时间作为x轴进行排列'''
data_keys=data.keys()
x_list = [i for i in data_keys]
greater_time=input('请输入指定的开始日期>>>>')
less_time=input('请输入指定的结束日期>>>>')
x_lists = []
time_type1='%Y-%m-%d' # 时间类型,后续可以添加
time_type2='%Y/%m/%d'
time_type3='%m-%d-%Y'
try:
star_time=datetime.datetime.strptime(greater_time,time_type1 or time_type2 or time_type3)
end_time=datetime.datetime.strptime(less_time,time_type1 or time_type2 or time_type3)
for i in x_list:
if end_time>datetime.datetime.strptime(i,time_type1 or time_type2 or time_type3)>star_time:
x_lists.append(i)
else:
pass
y_list=[float(data[i]) for i in x_lists]
return x_lists,y_list
except Exception as e:
try:
star_time=datetime.datetime.strptime(greater_time,time_type1 or time_type2 or time_type3)
end_time=datetime.datetime.strptime(less_time,time_type1 or time_type2 or time_type3)
for i in x_list:
if end_time>datetime.datetime.strptime(i,time_type1 or time_type2 or time_type3)>star_time:
x_lists.append(i)
else:
pass
y_list=[int(data[i]) for i in x_lists]
return x_lists,y_list
except Exception as e:
star_time=datetime.datetime.strptime(greater_time,time_type1 or time_type2 or time_type3)
end_time=datetime.datetime.strptime(less_time,time_type1 or time_type2 or time_type3)
for i in x_list:
if end_time>datetime.datetime.strptime(i,time_type1 or time_type2 or time_type3)>star_time:
x_lists.append(i)
else:
pass
y_list=[float(data[i].strip('%')) / 100.0 for i in x_lists]
return x_lists,y_list
class get_two_line_data_time(object):
# 当使用两行数据时通过过滤时间来x轴显示其他内容
def get_time_name_data(flie):
'''当使用时间参数时通过过滤时间来返回对应的x轴y轴'''
time_name = input('请选择时间列名称>>>>')
X_name = input('请选择x列名称>>>>')
Y_name = input('请选择y列名称>>>>')
with open('{}.csv'.format(flie), 'r')as f:
ride = csv.DictReader(f)
data = {}
data1={}
for i in ride:
data.update({i[time_name]: i[X_name]})
data1.update({i[time_name]: i[Y_name]})
return data,data1, X_name, Y_name
def scope_of_data_time_tag(data,data1):
'''首先获取时间返回 再通过时间范围来找到响应的其他内容来作为x轴'''
data_keys=data.keys()
time_list = [i for i in data_keys]
greater_time = input('请输入指定的开始日期>>>>')
less_time = input('请输入指定的结束日期>>>>')
x_lists = []
time_type1 = '%Y-%m-%d' # 时间类型,后续可以添加
time_type2 = '%Y/%m/%d'
time_type3 = '%m-%d-%Y'
star_time = datetime.datetime.strptime(greater_time, time_type1 or time_type2 or time_type3)
end_time = datetime.datetime.strptime(less_time, time_type1 or time_type2 or time_type3)
for i in time_list:
if end_time > datetime.datetime.strptime(i, time_type1 or time_type2 or time_type3) > star_time:
x_lists.append(i)
else:
pass
x_lists.sort()
try:
now_xlists=[data[i] for i in x_lists]
y_list=[int(data1[i]) for i in x_lists]
return now_xlists,y_list
except Exception as e:
try:
now_xlists = [data[i] for i in x_lists]
y_list = [float(data1[i]) for i in x_lists]
return now_xlists, y_list
except Exception as e:
now_xlists = [data[i] for i in x_lists]
y_list = [float(data[i].strip('%')) / 100.0 for i in
x_lists]
return now_xlists,y_list
class get_three_line_data(object):
# ---------------------------获取整体数据----------------------------------
def get_three_number_data(flie):
'''当需要两个参数时传入响应的参数'''
X_name = input('请选择X列名称>>>>')
Y_name = input('请选择第一个Y列名称>>>>')
Y1_name = input('请输入第二个Y列名称>>>>')
with open('{}.csv'.format(flie), 'r')as f:
ride = csv.DictReader(f)
data = {}
data1 = {}
for i in ride:
data.update({i[X_name]: i[Y_name]})
data1.update({i[X_name]: i[Y1_name]})
return data, data1, X_name, Y_name, Y1_name
#---------------------------对数据再次进行分类返回----------------------------------
def list_number(data, data1): # 根据设置列表数量进行排序
'''对添加的字典值再次根据不同的情况进行分析,并返回图表的X列Y列'''
data_keys = data.keys() # 获取字典中的键
x_list = [i for i in data_keys] # 根据字典中的键作为x列
list_number = int(input('请输入数据数量界限>>>>'))
if list_number > len(x_list):
try:
y_list = [float(data[i]) for i in x_list] # 根据x的键来查询字典中对应值
y_list2 = [float(data1[i]) for i in x_list]
return x_list, y_list, y_list2
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_list] # 根据x的键来查询字典中对应值
y_list2 = [int(data1[i]) for i in x_list]
return x_list, y_list, y_list2
except ValueError as e:
y_list = [float(data[i].strip('%')) * 100.0 for i in x_list] # 根据x的键来查询字典中对应值
y_list2 = [float(data1[i].strip('%')) * 100.0 for i in x_list]
return x_list, y_list, y_list2
else:
try:
y_list = [float(data[i]) for i in x_list[:list_number]]
y_list2 = [float(data1[i]) for i in x_list[:list_number]]
return x_list[:list_number], y_list, y_list2
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_list[:list_number]] # 根据x的键来查询字典中对应值
y_list2 = [int(data1[i]) for i in x_list[:list_number]]
return x_list[:list_number], y_list, y_list2
except ValueError as e:
y_list = [float(data[i].strip('%')) / 100.0 for i in x_list[:list_number]] # 根据x的键来查询字典中对应值
y_list2 = [float(data1[i].strip('%')) / 100.0 for i in x_list[:list_number]]
return x_list[:list_number], y_list, y_list2
def scope_of_data(data, data1):
''''''
data_keys = data.keys()
x_list = [i for i in data_keys]
greater = int(input('请输入大于某个数>>>>'))
less = int(input('请输入小于某个数>>>>'))
x_lists = []
for i in x_list:
if less > int(i) > greater:
x_lists.append(i)
else:
pass
try:
y_list = [float(data[i]) for i in x_lists]
y_list1 = [float(data1[i]) for i in x_lists]
return x_lists, y_list, y_list1
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_lists]
y_list1 = [int(data1[i]) for i in x_lists]
return x_lists, y_list, y_list1
except ValueError as e:
# y_list = [float(data[i].strip('%')) / 100.0 for i in x_list[star_number-1:end_number]] # 根据x的键来查询字典中对应值
y_list = [float(data[i].strip('%')) / 100.0 for i in x_lists]
y_list1 = [float(data1[i].strip('%')) / 100.0 for i in x_lists]
return x_lists, y_list, y_list1
def op_list_number(data, data1):
data_keys = data.keys()
x_list = [i for i in data_keys]
star_number = int(input('数据开始>>>>'))
end_number = int(input('数据结束>>>>'))
x_lists = []
for i in x_list[star_number:end_number]:
x_lists.append(i)
try:
y_list = [float(data[i]) for i in x_lists]
y_list1 = [float(data1[i]) for i in x_lists]
return x_lists, y_list, y_list1
except ValueError as e:
try:
y_list = [int(data[i]) for i in x_lists]
y_list1 = [int(data1[i]) for i in x_lists]
return x_lists, y_list, y_list1
except ValueError as e:
# y_list = [float(data[i].strip('%')) / 100.0 for i in x_list[star_number-1:end_number]] # 根据x的键来查询字典中对应值
y_list = [float(data[i].strip('%')) / 100.0 for i in x_lists]
y_list1 = [float(data1[i].strip('%')) / 100.0 for i in x_lists]
return x_lists, y_list, y_list1
def scope_of_data_time(data, data1):
'''时间作为x轴进行排列'''
data_keys = data.keys()
x_list = [i for i in data_keys]
greater_time = input('请输入指定的开始日期>>>>')
less_time = input('请输入指定的结束日期>>>>')
x_lists = []
time_type1 = '%Y-%m-%d' # 时间类型,后续可以添加
time_type2 = '%Y/%m/%d'
time_type3 = '%m-%d-%Y'
try:
star_time = datetime.datetime.strptime(greater_time, time_type1 or time_type2 or time_type3)
end_time = datetime.datetime.strptime(less_time, time_type1 or time_type2 or time_type3)
for i in x_list:
if end_time > datetime.datetime.strptime(i, time_type1 or time_type2 or time_type3) > star_time:
x_lists.append(i)
else:
pass
x_lists.sort()
y_list = [data[i] for i in x_lists]
y_list1 = [data1[i] for i in x_lists]
return x_lists, y_list, y_list1
except Exception:
print('时间格式错误请重新输入。')
class get_three_line_data_time(object):
def get_time_name_data(flie):
'''当使用时间参数时通过过滤时间来返回对应的x轴y轴'''
time_name = input('请选择时间列名称>>>>')
X_name = input('请选择x列名称>>>>')
Y_name = input('请选择y列名称>>>>')
Y_name1 = input('请选择y1列名称>>>>')
with open('{}.csv'.format(flie), 'r')as f:
ride = csv.DictReader(f)
data = {}
data1 = {}
data2 = {}
for i in ride:
data.update({i[time_name]: i[X_name]})
data1.update({i[time_name]: i[Y_name]})
data2.update({i[time_name]: i[Y_name1]})
return data, data1, data2, X_name, Y_name, Y_name1
def scope_of_data_time_tag(data, data1, data2):
'''首先获取时间返回 再通过时间范围来找到响应的其他内容来作为x轴'''
data_keys = data.keys()
time_list = [i for i in data_keys]
greater_time = input('请输入指定的开始日期>>>>')
less_time = input('请输入指定的结束日期>>>>')
x_lists = []
time_type1 = '%Y-%m-%d' # 时间类型,后续可以添加
time_type2 = '%Y/%m/%d'
time_type3 = '%m-%d-%Y'
try:
star_time = datetime.datetime.strptime(greater_time, time_type1 or time_type2 or time_type3)
end_time = datetime.datetime.strptime(less_time, time_type1 or time_type2 or time_type3)
for i in time_list:
if end_time > datetime.datetime.strptime(i, time_type1 or time_type2 or time_type3) > star_time:
x_lists.append(i)
else:
pass
x_lists.sort()
now_xlists = [data[i] for i in x_lists]
y_list = [int(data1[i]) for i in x_lists]
y_list1 = [int(data2[i]) for i in x_lists]
return now_xlists, y_list, y_list1
except Exception as e:
try:
star_time = datetime.datetime.strptime(greater_time, time_type1 or time_type2 or time_type3)
end_time = datetime.datetime.strptime(less_time, time_type1 or time_type2 or time_type3)
for i in time_list:
if end_time > datetime.datetime.strptime(i, time_type1 or time_type2 or time_type3) > star_time:
x_lists.append(i)
else:
pass
x_lists.sort()
now_xlists = [data[i] for i in x_lists]
y_list = [float(data1[i]) for i in x_lists]
y_list1 = [float(data2[i]) for i in x_lists]
return now_xlists, y_list, y_list1
except Exception as e:
star_time = datetime.datetime.strptime(greater_time, time_type1 or time_type2 or time_type3)
end_time = datetime.datetime.strptime(less_time, time_type1 or time_type2 or time_type3)
for i in time_list:
if end_time > datetime.datetime.strptime(i, time_type1 or time_type2 or time_type3) > star_time:
x_lists.append(i)
else:
pass
x_lists.sort()
now_xlists = [data[i] for i in x_lists]
y_list = [float(data1[i].strip('%')) / 100.0 for i in x_lists]
y_list1 = [float(data2[i].strip('%')) / 100.0 for i in x_lists]
return now_xlists, y_list, y_list1
图表制作
import matplotlib.pyplot as plt
import numpy as np
import csv
from collections import Counter
'''以后需要增加新的图表类型就可以这里添加对应的类'''
class bar_menu(object):
def two_plt(x,y,x_name,y_name,flie_name):
#------------------------两个参数的条形图--------------------------------
'''绘制图形'''
print('''条形图类型
1:竖型图
2:横型图''')
bar_menu=input('请输入要使用的类型')
if bar_menu=='1':
plt.bar(range(len(x)),y,color='orange',width=0.3,label=y_name)
plt.xticks(range(len(x)),x,rotation=45)
plt.xlabel(x_name,fontsize=15)#x轴标签
plt.ylabel(y_name,fontsize=15)#y轴标签
plt.title(flie_name,fontsize=15)#整体标签
for x,y in enumerate(y):
'''在柱形图上上显示具体的数值,ha参数控制水平对齐方式,va控制垂直对齐方式'''
plt.text(x,y,y,ha='center',va='bottom')
plt.grid(alpha=0.3) # 图表背景
'''
'best' : 0, (only implemented for axes legends)(自适应方式)
'upper right' : 1, 右上方
'upper left' : 2, 左上方
'lower left' : 3, 左下方
'lower right' : 4, 右下方
'right' : 5, 右方
'center left' : 6, 中心向左
'center right' : 7, 中心向右
'lower center' : 8, 下方中心
'upper center' : 9, 上方中心
'center' : 10, 中心对齐
'''
plt.legend(loc=1)
plt.show()
else:
plt.barh(range(len(x)),y,height=0.3,color='orange',label=y_name)
plt.yticks(range(len(x)),x)
plt.xlabel(y_name, fontsize=15) # x轴标签
plt.ylabel(x_name, fontsize=15) # y轴标签
plt.title(flie_name, fontsize=15) # 整体标签
plt.legend(loc=1) # 图例位于图表左上方
plt.grid(alpha=0.3)#显示背景坐标轴
plt.show()
def three_bar(x, y, y1, x_name, y_name, y1_name, title):
bar_with = 0.45 # 设置条形图宽度
print('''多参数统计图类型
1,堆积统计图
2,并列统计图''')
op_menu_type = int(input('请输入使用统计图类型:'))
if op_menu_type == 1:
print('''统计图放置类型
1:横型图
2:竖型图''')
op_one_menu = int(input('请选择统计图放置类型:'))
if op_one_menu == 1:
plt.bar(np.arange(len(x)), y, label=y_name, color='steelblue', alpha=0.8, width=bar_with)
plt.bar(np.arange(len(x)) + bar_with, y1, label=y1_name, color='indianred', alpha=0.8,
width=bar_with)
plt.title(title)
plt.xticks(np.arange(len(x)), x)
for a, b in zip(np.arange(len(x)),y):
c=str(b)
plt.text(a, b, c[:5] if len(c)>5 and '.' in c else c,ha='center', va='bottom')
for a, b in zip(np.arange(len(x)),y1):
c=str(b)
plt.text(a+bar_with, b, c[:5] if len(c)>5 and '.' in c else c,ha='center', va='bottom')
plt.xlabel(x_name)
plt.legend(loc=1)
plt.show()
else:
plt.barh(np.arange(len(x)), y, label=y_name, color='steelblue', alpha=0.8, height=bar_with)
plt.barh(np.arange(len(x)) + bar_with, y1, label=y1_name, color='indianred', alpha=0.8,
height=bar_with)
plt.yticks(np.arange(len(x)), x)
plt.legend(loc=1)
plt.title(title)
# for a, b in zip(np.arange(len(x)),np.arange(len(y))):
# c=str(b)
# plt.text(b, a, c[:5] if len(c)>5 and '.' in c else c,ha='center', va='bottom')
# for a, b in zip(np.arange(len(x)),y1):
# c=str(b)
# plt.text(a+bar_with, b, c[:5] if len(c)>5 and '.' in c else c,ha='center', va='bottom')
plt.xlabel(y_name)
plt.ylabel(x_name)
plt.grid(alpha=0.3)
plt.show()
else:
pass
class plots_menu(object):
# ------------------------两个参数的折线图--------------------------------
'''绘制图形'''
def two_plt(x,y,x_name,y_name,title):
'''传入两个参数时的折线图'''
plt.plot(x,y,marker='o',c='red',label=y_name) # label后边跟对应的名称 形成图例
plt.ylabel(r'{}'.format(y_name), fontdict={'size': 20})# y轴标签
plt.xlabel(r'{}'.format(x_name), fontdict={'size': 20})# x轴标签
if len(max(x))>5: # 判读x轴中最大值的长度,如果长度大于5x轴标签则旋转30度
plt.xticks(rotation=30)
else:
pass
for a,b in zip(x,y):
if type(b)==float:# 如果此刻的b为浮点型数据则取小数点的后两位
plt.text(a, b,str(b).split('.')[0]+'.'+str(b).split('.')[1][:2], ha='center', fontsize=10)
else:
plt.text(a, b, b, ha='center', fontsize=10)
plt.legend(loc=1) # 设置图例位置为统计表的左上方
plt.title(title)
plt.show()
# ------------------------三个参数的折线图--------------------------------
def three_plt(x, y, y1, x_name, y_name, y1_name, title):
'''传入三个参数时的折线图'''
plt.plot(x, y, marker='o', c='red', label=y_name)
plt.xlabel(r'{}'.format(x_name), fontdict={'size': 20})
for a, b in zip(x, y):
if type(b) == float:
plt.text(a, b, float(str(b).split('.')[0] + '.' + str(b).split('.')[1][:2]) * 100.0, ha='center',
fontsize=10)
else:
plt.text(a, b, b, ha='center', fontsize=10)
for a, b in zip(x, y1):
if type(b) == float:
plt.text(a, b, float(str(b).split('.')[0] + '.' + str(b).split('.')[1][:2]) * 100.0, ha='center',
fontsize=10)
else:
plt.text(a, b, b, ha='center', fontsize=10)
plt.title(title)
plt.plot(x, y1, marker='o', c='blue', label=y1_name)
if len(max(x)) > 5:
plt.xticks(rotation=30)
plt.legend()
plt.show()
class pie_menu(object):
#绘制饼图
#—————————————————————————统计一个标签类型—————————————————————————————————————
def get_menu(flie):
name_tag=input('请输入要统计的标签:')
data = []
with open('{}.csv'.format(flie), 'r')as f:
ride = csv.DictReader(f)
for i in ride:
data.append(i[name_tag])
set_data=set(data)
cout = Counter(data)
list(set_data)
dict(cout)
new_list=[]
for i in set_data:
new_list.append(cout[i])
return new_list,set_data,name_tag
def plt_menu(x,y,title):
explode_list=[]
for i in range(len(x)):
if i == 0:
explode_list.append(i)
else:
explode_list.append(0)
max_number=max(x)#获取列表中的最大值
rec_max=x.index(max_number)#获取列表中最大值的位置
explode_list[rec_max]=0.15#更改元组对应位置的数值
min_number=min(x)
rec_min=x.index(min_number)
explode_list[rec_min]=0.1
explode=tuple(explode_list)
#explode:对图形中设置对应位置里圆心的位置
plt.pie(x,explode=explode,labels=y,autopct='%1.1f%%',shadow=True,startangle=150)
plt.legend(y,loc="upper right", fontsize=10, bbox_to_anchor=(1.1, 1.05), borderaxespad=0.3,ncol=2)
plt.title(title,fontdict={'size': 20},va='center')
plt.show()