Python
import numpy as np import pandas as pd import matplotlib.pyplot as plt import random import time import threading from matplotlib.animation import FuncAnimation from matplotlib.gridspec import GridSpec from datetime import datetime, timedelta import warnings warnings.filterwarnings('ignore') plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False class AdvancedDataAnalyzer: def __init__(self): self.data = pd.DataFrame() self.is_running = True self.fig = plt.figure(figsize=(16, 10), facecolor='#f8f9fa') self.gs = GridSpec(3, 3, figure=self.fig, hspace=0.3, wspace=0.3) self.real_time_data = [] self.categories = ['产品A', '产品B', '产品C', '产品D', '产品E'] self.regions = ['华北', '华东', '华南', '西南', '西北', '东北'] self.stats_history = { 'mean': [], 'max': [], 'min': [], 'std': [] } self.init_subplots() def init_subplots(self): self.ax1 = self.fig.add_subplot(self.gs[0, 0]) self.ax2 = self.fig.add_subplot(self.gs[0, 1]) self.ax3 = self.fig.add_subplot(self.gs[0, 2]) self.ax4 = self.fig.add_subplot(self.gs[1, 0]) self.ax5 = self.fig.add_subplot(self.gs[1, 1]) self.ax6 = self.fig.add_subplot(self.gs[1, 2]) self.ax7 = self.fig.add_subplot(self.gs[2, :]) self.ax1.set_title('实时销售趋势', fontsize=12, fontweight='bold', color='#2c3e50') self.ax2.set_title('产品销量分布', fontsize=12, fontweight='bold', color='#2c3e50') self.ax3.set_title('区域销售占比', fontsize=12, fontweight='bold', color='#2c3e50') self.ax4.set_title('价格波动曲线', fontsize=12, fontweight='bold', color='#2c3e50') self.ax5.set_title('销量热力分布', fontsize=12, fontweight='bold', color='#2c3e50') self.ax6.set_title('统计指标变化', fontsize=12, fontweight='bold', color='#2c3e50') self.ax7.set_title('综合数据分析报告', fontsize=14, fontweight='bold', color='#2c3e50') for ax in [self.ax1, self.ax2, self.ax3, self.ax4, self.ax5, self.ax6, self.ax7]: ax.grid(True, alpha=0.3, linestyle='--') ax.set_facecolor('#ffffff') for spine in ax.spines.values(): spine.set_color('#bdc3c7') def generate_mock_data(self): start_date = datetime.now() - timedelta(days=30) dates = [start_date + timedelta(days=i) for i in range(30)] data_list = [] for date in dates: for category in self.categories: for region in self.regions: sales = random.randint(100, 1000) price = round(random.uniform(20, 200), 2) cost = round(price * random.uniform(0.4, 0.7), 2) profit = round((price - cost) * sales, 2) data_list.append({ '日期': date, '产品': category, '区域': region, '销量': sales, '单价': price, '成本': cost, '利润': profit }) self.data = pd.DataFrame(data_list) return self.data def generate_real_time_data(self): while self.is_running: new_sales = random.randint(300, 800) self.real_time_data.append(new_sales) if len(self.real_time_data) > 50: self.real_time_data.pop(0) time.sleep(0.5) def update_stats(self): if len(self.data) > 0: current_mean = self.data['销量'].mean() current_max = self.data['销量'].max() current_min = self.data['销量'].min() current_std = self.data['销量'].std() self.stats_history['mean'].append(current_mean) self.stats_history['max'].append(current_max) self.stats_history['min'].append(current_min) self.stats_history['std'].append(current_std) for key in self.stats_history: if len(self.stats_history[key]) > 20: self.stats_history[key].pop(0) def update_charts(self, frame): if len(self.data) == 0: self.generate_mock_data() self.update_stats() data = self.data real_time = self.real_time_data[-50:] if len(self.real_time_data) >= 50 else self.real_time_data self.ax1.clear() self.ax1.plot(range(len(real_time)), real_time, color='#3498db', linewidth=2, marker='o', markersize=3) self.ax1.set_title('实时销售趋势', fontsize=12, fontweight='bold', color='#2c3e50') self.ax1.fill_between(range(len(real_time)), real_time, alpha=0.2, color='#3498db') self.ax1.grid(True, alpha=0.3) self.ax2.clear() product_sales = data.groupby('产品')['销量'].sum().sort_values(ascending=True) colors = plt.cm.viridis(np.linspace(0, 1, len(product_sales))) bars = self.ax2.barh(product_sales.index, product_sales.values, color=colors) self.ax2.set_title('产品销量分布', fontsize=12, fontweight='bold', color='#2c3e50') for bar in bars: width = bar.get_width() self.ax2.text(width + 10, bar.get_y() + bar.get_height()/2, f'{int(width)}', ha='left', va='center', fontsize=9) self.ax3.clear() region_sales = data.groupby('区域')['销量'].sum() wedges, texts, autotexts = self.ax3.pie(region_sales.values, labels=region_sales.index, autopct='%1.1f%%', startangle=90, colors=plt.cm.Set3(np.linspace(0, 1, len(region_sales)))) self.ax3.set_title('区域销售占比', fontsize=12, fontweight='bold', color='#2c3e50') self.ax4.clear() price_trend = data.groupby(data['日期'].dt.date)['单价'].mean() self.ax4.plot(price_trend.index, price_trend.values, color='#e74c3c', linewidth=2) self.ax4.set_title('价格波动曲线', fontsize=12, fontweight='bold', color='#2c3e50') self.ax4.tick_params(axis='x', rotation=45, labelsize=8) self.ax5.clear() pivot_data = data.pivot_table(index='区域', columns='产品', values='销量', aggfunc='sum') im = self.ax5.imshow(pivot_data.values, cmap='YlOrRd', aspect='auto') self.ax5.set_xticks(range(len(self.categories))) self.ax5.set_xticklabels(self.categories, rotation=45) self.ax5.set_yticks(range(len(self.regions))) self.ax5.set_yticklabels(self.regions) self.ax5.set_title('销量热力分布', fontsize=12, fontweight='bold', color='#2c3e50') self.ax6.clear() if len(self.stats_history['mean']) > 0: self.ax6.plot(self.stats_history['mean'], label='平均销量', color='#2ecc71', linewidth=2) self.ax6.plot(self.stats_history['max'], label='最高销量', color='#f39c12', linewidth=2) self.ax6.plot(self.stats_history['min'], label='最低销量', color='#9b59b6', linewidth=2) self.ax6.legend(fontsize=8) self.ax6.set_title('统计指标变化', fontsize=12, fontweight='bold', color='#2c3e50') self.ax7.clear() total_sales = int(data['销量'].sum()) total_profit = round(data['profit'].sum(), 2) if 'profit' in data.columns else 0 avg_price = round(data['单价'].mean(), 2) best_product = data.groupby('产品')['销量'].sum().idxmax() best_region = data.groupby('区域')['销量'].sum().idxmax() report_text = f""" 【实时数据分析报告】 总销量:{total_sales:,} 件 总利润:{total_profit:,} 元 平均单价:{avg_price} 元 最佳产品:{best_product} 最佳区域:{best_region} 数据更新时间:{datetime.now().strftime('%H:%M:%S')} 系统状态:运行中 ● 数据维度:7大指标 ● 覆盖区域:6个 ● 产品种类:5种 """ self.ax7.text(0.05, 0.5, report_text, transform=self.ax7.transAxes, fontsize=12, verticalalignment='center', bbox=dict(boxstyle='round,pad=1', facecolor='#ecf0f1', alpha=0.8)) self.ax7.set_title('综合数据分析报告', fontsize=14, fontweight='bold', color='#2c3e50') self.ax7.set_xticks([]) self.ax7.set_yticks([]) plt.tight_layout() return [self.ax1, self.ax2, self.ax3, self.ax4, self.ax5, self.ax6, self.ax7] def start_analysis(self): print("=" * 60) print("🚀 高级Python数据分析可视化系统启动中...") print("📊 功能:实时数据生成 | 多维度图表 | 智能分析 | 动态刷新") print("=" * 60) data_thread = threading.Thread(target=self.generate_real_time_data, daemon=True) data_thread.start() ani = FuncAnimation(self.fig, self.update_charts, interval=1000, cache_frame_data=False) try: plt.show() except KeyboardInterrupt: print("\n✅ 系统已安全退出") finally: self.is_running = False if __name__ == "__main__": analyzer = AdvancedDataAnalyzer() analyzer.start_analysis()