import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import pandas as pd
def generate_chart(df, chart_type, title, x_label, y_label, legend, **kwargs):
try:
if chart_type == "line":
fig = px.line(df, x=kwargs["x_column"], y=kwargs["y_column"],
title=title, labels={kwargs["x_column"]: x_label, kwargs["y_column"]: y_label})
elif chart_type == "bar":
fig = px.bar(df, x=kwargs["x_column"], y=kwargs["y_column"],
title=title, labels={kwargs["x_column"]: x_label, kwargs["y_column"]: y_label})
elif chart_type == "histogram":
fig = px.histogram(df, x=kwargs["x_column"],
title=title, labels={kwargs["x_column"]: x_label, "count": y_label})
elif chart_type == "scatter":
fig = px.scatter(df, x=kwargs["x_column"], y=kwargs["y_column"],
title=title, labels={kwargs["x_column"]: x_label, kwargs["y_column"]: y_label})
elif chart_type == "pie":
fig = px.pie(df, values=kwargs["values_column"], names=kwargs["names_column"], title=title)
elif chart_type == "heatmap":
corr = df.corr()
fig = px.imshow(corr, cmap="coolwarm", title=title)
else:
print("不支持的图表类型")
return
if legend:
fig.update_layout(legend_title_text="Legend")
fig.show()
except Exception as e:
print(f"生成图表失败:{e}")
import tkinter as tk
from tkinter import filedialog, messagebox
import pandas as pd
import os
from data_reader import read_data
from chart_generator import generate_chart
class DataVisualizationApp:
def __init__(self, root):
self.root = root
self.root.title("数据可视化系统")
self.file_label = tk.Label(root, text="数据文件:")
self.file_label.grid(row=0, column=0, padx=10, pady=10, sticky=tk.W)
self.file_entry = tk.Entry(root, width=50)
self.file_entry.grid(row=0, column=1, padx=10, pady=10)
self.browse_button = tk.Button(root, text="浏览", command=self.browse_file)
self.browse_button.grid(row=0, column=2, padx=10, pady=10)
self.chart_type_label = tk.Label(root, text="图表类型:")
self.chart_type_label.grid(row=1, column=0, padx=10, pady=10, sticky=tk.W)
self.chart_type_var = tk.StringVar(value="line")
self.chart_type_menu = tk.OptionMenu(root, self.chart_type_var, "line", "bar", "histogram", "scatter", "pie", "heatmap")
self.chart_type_menu.grid(row=1, column=1, padx=10, pady=10, sticky=tk.W)
self.title_label = tk.Label(root, text="标题:")
self.title_label.grid(row=2, column=0, padx=10, pady=10, sticky=tk.W)
self.title_entry = tk.Entry(root, width=50)
self.title_entry.grid(row=2, column=1, padx=10, pady=10)
self.x_label_label = tk.Label(root, text="X 轴标签:")
self.x_label_label.grid(row=3, column=0, padx=10, pady=10, sticky=tk.W)
self.x_label_entry = tk.Entry(root, width=50)
self.x_label_entry.grid(row=3, column=1, padx=10, pady=10)
self.y_label_label = tk.Label(root, text="Y 轴标签:")
self.y_label_label.grid(row=4, column=0, padx=10, pady=10, sticky=tk.W)
self.y_label_entry = tk.Entry(root, width=50)
self.y_label_entry.grid(row=4, column=1, padx=10, pady=10)
self.legend_var = tk.BooleanVar()
self.legend_checkbox = tk.Checkbutton(root, text="显示图例", variable=self.legend_var)
self.legend_checkbox.grid(row=5, column=0, columnspan=3, padx=10, pady=10, sticky=tk.W)
self.generate_button = tk.Button(root, text="生成图表", command=self.generate_chart)
self.generate_button.grid(row=6, column=0, columnspan=3, padx=10, pady=10)
self.export_label = tk.Label(root, text="导出路径:")
self.export_label.grid(row=7, column=0, padx=10, pady=10, sticky=tk.W)
self.export_entry = tk.Entry(root, width=50)
self.export_entry.grid(row=7, column=1, padx=10, pady=10)
self.browse_export_button = tk.Button(root, text="浏览", command=self.browse_export_path)
self.browse_export_button.grid(row=7, column=2, padx=10, pady=10)
self.export_button = tk.Button(root, text="导出图表", command=self.export_chart)
self.export_button.grid(row=8, column=0, columnspan=3, padx=10, pady=10)
def browse_file(self):
file_path = filedialog.askopenfilename(filetypes=[("CSV 文件", "*.csv")])
if file_path:
self.file_entry.delete(0, tk.END)
self.file_entry.insert(0, file_path)
def browse_export_path(self):
export_path = filedialog.asksaveasfilename(defaultextension=".png",
filetypes=[("PNG 文件", "*.png"), ("JPEG 文件", "*.jpeg"), ("SVG 文件", "*.svg")])
if export_path:
self.export_entry.delete(0, tk.END)
self.export_entry.insert(0, export_path)
def generate_chart(self):
file_path = self.file_entry.get()
if not file_path:
messagebox.showerror("错误", "请选择数据文件")
return
df = read_data(file_path)
if df is None:
return
chart_type = self.chart_type_var.get()
title = self.title_entry.get()
x_label = self.x_label_entry.get()
y_label = self.y_label_entry.get()
legend = self.legend_var.get()
kwargs = {}
if chart_type in ["line", "bar", "scatter"]:
x_column = input("请输入 X 轴列名:")
y_column = input("请输入 Y 轴列名:")
kwargs["x_column"] = x_column
kwargs["y_column"] = y_column
elif chart_type == "histogram":
x_column = input("请输入 X 轴列名:")
kwargs["x_column"] = x_column
elif chart_type == "pie":
values_column = input("请输入数值列名:")
names_column = input("请输入名称列名:")
kwargs["values_column"] = values_column
kwargs["names_column"] = names_column
generate_chart(df, chart_type, title, x_label, y_label, legend, **kwargs)
def export_chart(self):
file_path = self.file_entry.get()
if not file_path:
messagebox.showerror("错误", "请选择数据文件")
return
df = read_data(file_path)
if df is None:
return
export_path = self.export_entry.get()
if not export_path:
messagebox.showerror("错误", "请选择导出路径")
return
chart_type = self.chart_type_var.get()
title = self.title_entry.get()
x_label = self.x_label_entry.get()
y_label = self.y_label_entry.get()
legend = self.legend_var.get()
kwargs = {}
if chart_type in ["line", "bar", "scatter"]:
x_column = input("请输入 X 轴列名:")
y_column = input("请输入 Y 轴列名:")
kwargs["x_column"] = x_column
kwargs["y_column"] = y_column
elif chart_type == "histogram":
x_column = input("请输入 X 轴列名:")
kwargs["x_column"] = x_column
elif chart_type == "pie":
values_column = input("请输入数值列名:")
names_column = input("请输入名称列名:")
kwargs["values_column"] = values_column
kwargs["names_column"] = names_column
try:
if chart_type == "line":
fig = px.line(df, x=kwargs["x_column"], y=kwargs["y_column"], title=title)
elif chart_type == "bar":
fig = px.bar(df, x=kwargs["x_column"], y=kwargs["y_column"], title=title)
elif chart_type == "histogram":
fig = px.histogram(df, x=kwargs["x_column"], title=title)
elif chart_type == "scatter":
fig = px.scatter(df, x=kwargs["x_column"], y=kwargs["y_column"], title=title)
elif chart_type == "pie":
fig = px.pie(df, values=kwargs["values_column"], names=kwargs["names_column"], title=title)
elif chart_type == "heatmap":
corr = df.corr()
fig = px.imshow(corr, cmap="coolwarm", title=title)
fig.write_image(export_path)
messagebox.showinfo("成功", "图表已导出")
except Exception as e:
print(f"导出图表失败:{e}")
if __name__ == "__main__":
root = tk.Tk()
app = DataVisualizationApp(root)
root.mainloop()