通过 Python 读取 XLS 、CSV文件中的数据,对数据进行处理,然后生成包含柱状图、扇形图和折线图的 HTML 报告。这个方案使用了 pandas
处理数据,matplotlib
生成图表,并将图表嵌入到 HTML 页面中。
1.XSL文件生成可视化图像、生成html页面
此代码根据DATA1.xls文件将数据经过panda库处理后,由matplotlib生成柱形图、折线图、扇形图,并且将图片嵌入HTML页面,让数据更加清晰。
matplotlib1.py
# coding=utf-8
import pandas as pd
import matplotlib.pyplot as plt
import os
from datetime import datetime
import xlrd
import xlwt
from openpyxl import load_workbook
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
def read_excel_data(file_path):
"""读取 Excel 文件数据"""
try:
df = pd.read_excel(file_path)
print(f"成功读取文件: {file_path}")
print(f"数据包含 {df.shape[0]} 行,{df.shape[1]} 列")
print(f"列名: {', '.join(df.columns.tolist())}")
return df
except Exception as e:
print(f"读取 Excel 文件出错: {e}")
return None
def generate_bar_chart(data, x_col, y_col, output_path):
"""生成柱状图"""
plt.figure(figsize=(10, 6))
plt.bar(data[x_col], data[y_col])
plt.title(f"{y_col} 分布柱状图")
plt.xlabel(x_col)
plt.ylabel(y_col)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig(output_path)
plt.close()
def generate_pie_chart(data, category_col, value_col, output_path):
"""生成扇形图"""
plt.figure(figsize=(8, 8))
plt.pie(data[value_col], labels=data[category_col], autopct='%1.1f%%', startangle=90)
plt.title(f"{value_col} 分布扇形图")
plt.tight_layout()
plt.savefig(output_path)
plt.close()
def generate_line_chart(data, x_col, y_col, output_path):
"""生成折线图"""
plt.figure(figsize=(10, 6))
plt.plot(data[x_col], data[y_col], marker='o')
plt.title(f"{y_col} 趋势折线图")
plt.xlabel(x_col)
plt.ylabel(y_col)
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.savefig(output_path)
plt.close()
def generate_html_report(chart_paths, output_path):
"""生成 HTML 报告"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
html_content = f"""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数据可视化报告</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 20px; }}
h1, h2 {{ color: #333; }}
.chart-container {{ margin-bottom: 40px; }}
img {{ max-width: 100%; height: auto; box-shadow: 0 4px 8px rgba(0,0,0,0.1); }}
.timestamp {{ color: #666; font-size: 0.9em; }}
</style>
</head>
<body>
<h1>数据可视化报告</h1>
<p class="timestamp">生成时间: {timestamp}</p>
{''.join([f'<div class="chart-container"><h2>{title}</h2><img src="{title}.png" alt="{title}"></div>'
for title, path in chart_paths.items()])}
<footer>
<p>© 2023 数据可视化工具</p>
</footer>
</body>
</html>
"""
with open(output_path, 'w', encoding='utf-8') as f:
f.write(html_content)
def main():
# 文件路径设置
xls_file = 'C:/Users/IT14/Desktop/DATA1.xls' # 请替换为实际的 XLS 文件路径
output_html = 'data_visualization_report.html'
# 读取数据
df = read_excel_data(xls_file)
if df is None or df.empty:
print("无法读取数据或数据为空,程序退出。")
return
# 生成图表(根据实际数据结构调整列名)
chart_data = {}
# 示例:假设 XLS 文件包含以下列
# - 产品名称
# - 销售额
# - 销量
# - 日期
# 检查列是否存在
required_columns = ['产品名称', '销售额', '销量', '日期']
missing_columns = [col for col in required_columns if col not in df.columns]
if missing_columns:
print(f"错误:数据中缺少以下列: {', '.join(missing_columns)}")
print(f"可用列: {', '.join(df.columns.tolist())}")
print("请根据实际数据结构修改代码中的列名。")
return
# 生成柱状图(销售额分布)
chart_data['产品销售额分布柱状图'] = generate_bar_chart(
df, '产品名称', '销售额', '产品销售额分布柱状图')
# 生成扇形图(销量占比)
chart_data['产品销量占比扇形图'] = generate_pie_chart(
df, '产品名称', '销量', '产品销量占比扇形图')
# 生成折线图(销售额趋势)
chart_data['销售额趋势折线图'] = generate_line_chart(
df, '日期', '销售额', '销售额趋势折线图')
# 生成 HTML 报告
generate_html_report(chart_data, output_html)
print("报告生成完成,请在浏览器中打开 HTML 文件查看。")
if __name__ == "__main__":
main()
2. CSV文件生成可视化图像
2.1 matplotblib-折线图
此代码根据sitka_weather_2018_simple.csv文件广州气温数据和日期生成一个折线图
matplotlib-折线图.py
import csv
from datetime import datetime
import matplotlib
import matplotlib.pyplot as plt
# 设置中文字体
matplotlib.rc("font",family='MicroSoft YaHei',weight="bold")
# 1.读取scv文件
filename = 'C:/Users/IT14/Desktop/sitka_weather_2018_simple.csv'
# 1.1.创建阅读器
with open(filename) as filename_list:
# 1.2.创建阅读器csv.reader()
reader = csv.reader(filename_list);
# 1.3.获取表头
header_name = next(reader)
# 2.打印数据
for index,column_value in enumerate(header_name):
print(index,column_value)
# 3.获取数据
TMAX ,TDATE,TMIN= [],[],[]
for max in reader:
TMAX.append(int(max[5]))
TDATE.append(datetime.strptime(max[2],'%Y-%m-%d'))
TMIN.append(int(max[6]))
print(TMAX)
# 4.绘图-折线图
fig = plt.figure(dpi=128,figsize=(8,6))
plt1=plt.plot(TDATE,TMAX,c='red',label='最高气温')
plt2=plt.plot(TDATE,TMIN,c='blue',label='最低气温')
for a,b in zip(TDATE,TMAX):
plt.text(a,b+1,b)
for a,b in zip(TDATE,TMIN):
plt.text(a,b-2,b)
plt.fill_between(TDATE,TMAX,TMIN,facecolor='blue',alpha=0.1)
fig.autofmt_xdate()
# 5.设置格式
plt.title("2018年广州气温数据",fontsize=24)
plt.xlabel('年-月-日',fontsize=16)
plt.ylabel('气温(度)',fontsize=16)
plt.tick_params(axis='both',labelsize=16)
plt.legend()
plt.savefig('气温折线图.png')
plt.show()
2.2 matplotblib-柱形图
此代码根据sitka_weather_2018_simple.csv文件最大销售量、最低销售量和日期生成一个柱形图。
matplotlib-柱形图.py
import pandas as pd
# 读取数据,填写文件路径,配置
data = pd.read_csv('C:/Users/IT14/Desktop/sitka_weather_2018_simple.csv',encoding="ANSI",usecols=['DATE','TMAX','TMIN'])
# 取消最大显示行数和列数限制
pd.options.display.max_columns=None
pd.options.display.max_rows=None
# 选择行
data_1 = data.head(2)
print(data_1)
# 查看数据尺寸
print(data.shape)
# 查看数据数量
print(data.size)
# 查看字段类型
print(data.dtypes)
# 查看数据信息
# print(data.info)
# 数据描述:只统计数值型数据
print(data.describe())
# 获取单个字段取值数目,normalize=True表示显示占比
# print(data['TMAX'].value_counts())
# cut函数
# print(pd.cut(range(10),bins=[0,10,20,30,40,50,60,70,80,90,100],right=True))
bins=[10,20,30,40,50,60,70,80,90,100,110]
boxes,lables = pd.cut(data['TMAX'],bins=bins,right=True,retbins=True,include_lowest=True)
print(lables)
print(boxes.value_counts().sort_index().values)
# 正常函数
data['DATE'] = pd.to_datetime(data['DATE'])
data = data.set_index('DATE')
print(data.head(4))
data = data.resample('ME').sum().to_period('M')
print(data.head(2))
print(data.dtypes)
print(str(data.index[0]))
sss = []
for index,dt in enumerate(data.index):
sss.append(dt)
TMAX,TMIN = [],[]
for dt in enumerate(data['TMAX']):
TMAX.append(int(dt[1]))
for dt in enumerate(data['TMIN']):
TMIN.append(int(dt[1]))
print(sss,TMAX,TMIN)
# 绘制柱形图
import matplotlib
import matplotlib.pyplot as plt
matplotlib.rc('font',family='MicroSoft YaHei',weight='bold')
# 设置画布大小
pl = plt.figure(figsize=(15,8))
#设置x,y轴
plt.ylabel('2018年销售量',fontsize=22)
plt.xlabel('月份',fontsize=22)
# 柱形图bar
plt.xticks(range(0,len(sss)),sss)
#设置两个柱形
plt1=plt.bar(range(0,len(sss)),TMAX,label='最高销售额',width=0.4)
plt2=plt.bar([i+0.4 for i in range(0,len(sss))],TMIN,label='最低销售额',width=0.4)
# 设置坐标
# for y in TMAX,TMIN:
# for a,b in zip(range(0,len(sss)),y):
# if y == TMIN:
# a+=0.4
# plt.text(a,b+2,b,ha='center')
plt.bar_label(plt1,label_type='edge')
plt.bar_label(plt2,label_type='edge')
pl.autofmt_xdate()
plt.legend()
#保存文件为图片
plt.savefig('销售额.png')
#在python编辑器打开图片
plt.show()
plt.close()
2.3 matplotblib-扇形图
此代码根据sales_data.csv文件最大销售量、最低销售量和日期生成一个扇形图图。
matplotlib-扇形图.py
import csv
import matplotlib.pyplot as plt
# 设置中文字体,确保中文正常显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
def read_csv_data(file_path, category_col, value_col):
"""
从 CSV 文件读取数据
参数:
file_path (str): CSV 文件路径
category_col (int): 分类列的索引(从0开始)
value_col (int): 数值列的索引(从0开始)
返回:
tuple: 包含分类列表和对应数值列表的元组
"""
categories = []
values = []
with open(file_path, 'r', encoding='gb18030') as file:
reader = csv.reader(file)
next(reader) # 跳过表头
for row in reader:
if len(row) > max(category_col, value_col):
categories.append(row[category_col])
values.append(float(row[value_col]))
return categories, values
def generate_pie_chart(categories, values, title, output_path=None):
"""
生成扇形图
参数:
categories (list): 分类列表
values (list): 对应数值列表
title (str): 图表标题
output_path (str, optional): 保存图片的路径,若为None则显示图表
"""
# 创建画布
plt.figure(figsize=(10, 8))
# 计算百分比总和,确保总和为100%
total = sum(values)
percentages = [v / total * 100 for v in values]
# 找出最大占比的项,用于突出显示
explode = [0.1 if p == max(percentages) else 0 for p in percentages]
# 自定义颜色
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#c2c2f0', '#ffb3e6']
# 绘制扇形图
plt.pie(
values,
explode=explode,
labels=categories,
colors=colors[:len(categories)],
autopct='%1.1f%%', # 显示百分比,保留一位小数
shadow=True, # 添加阴影
startangle=90 # 起始角度
)
# 设置为正圆形
plt.axis('equal')
# 添加标题
plt.title(title, fontsize=16)
# 添加图例
plt.legend(categories, loc="best")
# 如果指定了输出路径,则保存图片;否则显示图片
if output_path:
plt.savefig(output_path, dpi=300, bbox_inches='tight')
print(f"图表已保存至: {output_path}")
else:
plt.show()
def main():
# CSV 文件路径(请替换为实际文件路径)
csv_file = 'C:/Users/IT14/Desktop/sales_data.csv'
# 配置参数
category_column = 0 # 分类列索引(假设第一列是分类)
value_column = 1 # 数值列索引(假设第二列是数值)
chart_title = '销售数据分布扇形图'
# 读取数据
categories, values = read_csv_data(csv_file, category_column, value_column)
if not categories or not values:
print("没有足够的数据来生成图表")
return
# 生成并显示/保存图表
generate_pie_chart(categories, values, chart_title, output_path='sales_pie_chart.png')
if __name__ == "__main__":
main()