使用 Tkinter 和 Matplotlib 可视化性别分类数据集
import tkinter as tk
from tkinter import ttk
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 加载数据集
data = pd.read_csv('性别分类数据集0.csv')
# 创建主窗口
root = tk.Tk()
root.title('数据可视化')
root.geometry('800x600')
# 创建下拉列表选择性别
gender_label = ttk.Label(root, text='请选择性别')
gender_label.pack(pady=10)
gender_var = tk.StringVar(value='1')
gender_combobox = ttk.Combobox(root, textvariable=gender_var, values=['男', '女'])
gender_combobox.pack()
# 创建下拉列表选择特征
feature_label = ttk.Label(root, text='请选择图的特征')
feature_label.pack(pady=10)
feature_var = tk.StringVar(value='forehead_width_cm')
feature_combobox = ttk.Combobox(root, textvariable=feature_var, values=['forehead_width_cm', 'forehead_height_cm', 'long_hair', 'nose_wide', 'nose_long', 'lips_thin', 'distance_nose_to_lip_long'])
feature_combobox.pack()
# 创建画布
canvas = tk.Canvas(root, width=600, height=400)
canvas.pack(pady=20)
def update_plot():
# 获取选择的性别和特征
gender = int(gender_var.get() == '男')
feature = feature_var.get()
# 根据选择的特征绘制不同的图形
if feature in ['forehead_width_cm', 'forehead_height_cm']:
# 绘制散点图
df = data[data['gender'] == gender][feature]
# 计算分组间隔
bin_width = (df.max() - df.min()) / 10
# 绘制直方图
plt.hist(df, bins=np.arange(df.min(), df.max()+bin_width, bin_width), align='mid', histtype='bar', rwidth=0.8)
plt.xlabel(feature)
plt.ylabel('count')
plt.savefig('temp.png') # 保存图像
plt.show()
else:
# 绘制柱状图
plt.bar([0, 1], [data[(data['gender'] == gender) & (data[feature] == 0)].shape[0], data[(data['gender'] == gender) & (data[feature] == 1)].shape[0]])
plt.xticks([0, 1], ['0', '1'])
plt.xlabel(feature)
plt.ylabel('count')
plt.title(f'{feature} ({gender})')
plt.savefig('temp.png') # 保存图像
# 清空画布并绘制新图
canvas.delete('all')
canvas.create_rectangle(0, 0, canvas.winfo_width(), canvas.winfo_height(), fill='white')
canvas.create_image(canvas.winfo_width() / 2, canvas.winfo_height() / 2, image=tk.PhotoImage(file='temp.png'))
# 创建按钮,并绑定更新图的函数
update_button = ttk.Button(root, text='更新图', command=update_plot)
update_button.pack(pady=10)
# 运行主循环
root.mainloop()
图片不显示在窗口中但是不报错的原因可能是:
- 图片保存路径错误: 在
plt.savefig('temp.png')中,没有指定完整的路径,导致图片无法正确加载。可以尝试在保存图像时指定完整的路径,比如:
plt.savefig('C:/Users/username/Desktop/temp.png') # 替换为实际路径
- 图片加载方式错误: 在更新画布时,没有使用正确的图片加载方式。可以使用
PIL库加载图片并将其显示在画布上:
from PIL import Image, ImageTk
# 绘制新图
new_img = Image.open('temp.png')
new_img = new_img.resize((canvas.winfo_width(), canvas.winfo_height()))
new_photo = ImageTk.PhotoImage(new_img)
# 更新画布
canvas.delete('all')
canvas.create_image(canvas.winfo_width() / 2, canvas.winfo_height() / 2, image=new_photo)
解决方法:
- 确保
temp.png文件已成功保存到指定的路径,并使用Image.open('temp.png')加载图片。 - 使用
canvas.create_image()将图片显示在画布上。
修改后的代码:
import tkinter as tk
from tkinter import ttk
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageTk
# 加载数据集
data = pd.read_csv('性别分类数据集0.csv')
# 创建主窗口
root = tk.Tk()
root.title('数据可视化')
root.geometry('800x600')
# 创建下拉列表选择性别
gender_label = ttk.Label(root, text='请选择性别')
gender_label.pack(pady=10)
gender_var = tk.StringVar(value='1')
gender_combobox = ttk.Combobox(root, textvariable=gender_var, values=['男', '女'])
gender_combobox.pack()
# 创建下拉列表选择特征
feature_label = ttk.Label(root, text='请选择图的特征')
feature_label.pack(pady=10)
feature_var = tk.StringVar(value='forehead_width_cm')
feature_combobox = ttk.Combobox(root, textvariable=feature_var, values=['forehead_width_cm', 'forehead_height_cm', 'long_hair', 'nose_wide', 'nose_long', 'lips_thin', 'distance_nose_to_lip_long'])
feature_combobox.pack()
# 创建画布
canvas = tk.Canvas(root, width=600, height=400)
canvas.pack(pady=20)
def update_plot():
# 获取选择的性别和特征
gender = int(gender_var.get() == '男')
feature = feature_var.get()
# 根据选择的特征绘制不同的图形
if feature in ['forehead_width_cm', 'forehead_height_cm']:
# 绘制散点图
df = data[data['gender'] == gender][feature]
# 计算分组间隔
bin_width = (df.max() - df.min()) / 10
# 绘制直方图
plt.hist(df, bins=np.arange(df.min(), df.max()+bin_width, bin_width), align='mid', histtype='bar', rwidth=0.8)
plt.xlabel(feature)
plt.ylabel('count')
plt.savefig('temp.png') # 保存图像
plt.show()
else:
# 绘制柱状图
plt.bar([0, 1], [data[(data['gender'] == gender) & (data[feature] == 0)].shape[0], data[(data['gender'] == gender) & (data[feature] == 1)].shape[0]])
plt.xticks([0, 1], ['0', '1'])
plt.xlabel(feature)
plt.ylabel('count')
plt.title(f'{feature} ({gender})')
plt.savefig('temp.png') # 保存图像
# 加载图片并显示在画布上
new_img = Image.open('temp.png')
new_img = new_img.resize((canvas.winfo_width(), canvas.winfo_height()))
new_photo = ImageTk.PhotoImage(new_img)
canvas.delete('all')
canvas.create_image(canvas.winfo_width() / 2, canvas.winfo_height() / 2, image=new_photo)
# 创建按钮,并绑定更新图的函数
update_button = ttk.Button(root, text='更新图', command=update_plot)
update_button.pack(pady=10)
# 运行主循环
root.mainloop()
原文地址: http://www.cveoy.top/t/topic/fYgj 著作权归作者所有。请勿转载和采集!