在大数据时代,我们每天都要面对海量的数据。然而,原始数据往往是枯燥和难以理解的,数据可视化通过图形化的方式,将复杂的数据转化为直观的图表,帮助我们:
Matplotlib是Python中最基础、最广泛使用的数据可视化库,本文将带你掌握Matplotlib的核心技能。
Matplotlib是Python中最基础、最广泛使用的数据可视化库,提供了底层的绘图API,支持各种类型的图表。
# 使用pip安装pip install matplotlib numpy pandas# 或使用conda安装conda install matplotlib numpy pandasimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdprint("Matplotlib版本:", plt.__version__)print("环境搭建成功!")折线图适合展示数据随时间变化的趋势。
import matplotlib.pyplot as pltimport numpy as np# 设置中文字体plt.rcParams["font.sans-serif"] = ["SimHei"]plt.rcParams["axes.unicode_minus"] = False# 准备数据x = np.linspace(0, 10, 100)y = np.sin(x)# 绘制折线图plt.figure(figsize=(10, 6))plt.plot(x, y, label='sin(x)', color='blue', linewidth=2, linestyle='-')plt.title('正弦函数曲线')plt.xlabel('x轴')plt.ylabel('y轴')plt.legend()plt.grid(True, alpha=0.3)plt.show()柱状图适合比较不同类别的数据。
# 准备数据categories = ['产品A', '产品B', '产品C', '产品D', '产品E']values = [23, 45, 12, 67, 34]colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']# 绘制柱状图plt.figure(figsize=(10, 6))bars = plt.bar(categories, values, color=colors, alpha=0.8, edgecolor='black')# 添加数值标签for bar in bars: height = bar.get_height() plt.text(bar.get_x() + bar.get_width()/2., height,f'{height}', ha='center', va='bottom')plt.title('不同产品的销售情况')plt.xlabel('产品类别')plt.ylabel('销售数量')plt.ylim(0, 75)plt.show()散点图适合展示两个变量之间的关系。
# 准备数据np.random.seed(42)x = np.random.rand(100)y = np.random.rand(100)colors = np.random.rand(100)sizes = 1000 * np.random.rand(100)# 绘制散点图plt.figure(figsize=(10, 6))scatter = plt.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis')plt.colorbar(scatter, label='颜色值')plt.title('散点图示例')plt.xlabel('X变量')plt.ylabel('Y变量')plt.show()直方图适合展示数据的分布情况。
# 准备数据np.random.seed(42)data = np.random.randn(1000)# 绘制直方图plt.figure(figsize=(10, 6))n, bins, patches = plt.hist(data, bins=30, alpha=0.7, color='skyblue', edgecolor='black', linewidth=1)# 添加均值线mean_val = np.mean(data)plt.axvline(mean_val, color='red', linestyle='--', linewidth=2, label=f'均值: {mean_val:.2f}')plt.legend()plt.title('数据分布直方图')plt.xlabel('数值')plt.ylabel('频率')plt.show()饼图适合展示各部分占整体的比例。
# 准备数据sizes = [30, 20, 25, 15, 10]labels = ['产品A', '产品B', '产品C', '产品D', '产品E']colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']explode = (0.1, 0, 0, 0, 0) # 突出显示第一个部分# 绘制饼图plt.figure(figsize=(8, 8))plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%', shadow=True, startangle=90, textprops={'fontsize': 12})plt.title('产品销售额占比')plt.axis('equal') # 保证饼图是圆形plt.show()import matplotlib.pyplot as pltimport numpy as np# 创建2x2的子图fig, axes = plt.subplots(2, 2, figsize=(12, 10))# 第一个子图:折线图x = np.linspace(0, 10, 100)y1 = np.sin(x)axes[0, 0].plot(x, y1, color='blue')axes[0, 0].set_title('正弦函数')axes[0, 0].set_xlabel('x')axes[0, 0].set_ylabel('sin(x)')axes[0, 0].grid(True, alpha=0.3)# 第二个子图:柱状图categories = ['A', 'B', 'C', 'D', 'E']values = [23, 45, 12, 67, 34]axes[0, 1].bar(categories, values, color='skyblue')axes[0, 1].set_title('柱状图')axes[0, 1].set_xlabel('类别')axes[0, 1].set_ylabel('值')# 第三个子图:散点图x_scatter = np.random.rand(50)y_scatter = np.random.rand(50)axes[1, 0].scatter(x_scatter, y_scatter, color='green', alpha=0.6)axes[1, 0].set_title('散点图')axes[1, 0].set_xlabel('x')axes[1, 0].set_ylabel('y')# 第四个子图:直方图data = np.random.randn(1000)axes[1, 1].hist(data, bins=30, color='orange', alpha=0.7)axes[1, 1].set_title('直方图')axes[1, 1].set_xlabel('值')axes[1, 1].set_ylabel('频率')plt.tight_layout() # 调整子图布局plt.show()# 使用gridspec自定义布局import matplotlib.gridspec as gridspecfig = plt.figure(figsize=(14, 8))gs = gridspec.GridSpec(3, 3, figure=fig)# 主图占据第一行全部ax1 = fig.add_subplot(gs[0, :])x = np.linspace(0, 10, 100)ax1.plot(x, np.sin(x), color='blue', linewidth=2)ax1.set_title('主图 - 正弦函数')ax1.grid(True, alpha=0.3)# 左侧两图ax2 = fig.add_subplot(gs[1:, 0])ax2.bar(['A', 'B', 'C'], [10, 20, 15], color='skyblue')ax2.set_title('柱状图')ax3 = fig.add_subplot(gs[1:, 1])ax3.scatter(np.random.rand(30), np.random.rand(30), color='green')ax3.set_title('散点图')# 右侧一图ax4 = fig.add_subplot(gs[1:, 2])data = np.random.randn(500)ax4.hist(data, bins=20, color='orange', alpha=0.7)ax4.set_title('直方图')plt.tight_layout()plt.show()# 查看可用的样式print(plt.style.available)# 使用ggplot风格plt.style.use('ggplot')# 绘制图表x = np.linspace(0, 10, 100)plt.figure(figsize=(10, 6))plt.plot(x, np.sin(x), label='sin(x)')plt.plot(x, np.cos(x), label='cos(x)')plt.title('使用ggplot风格')plt.legend()plt.grid(True)plt.show()# 恢复默认风格plt.style.use('default')plt.figure(figsize=(10, 6))# 自定义线条样式x = np.linspace(0, 10, 100)plt.plot(x, np.sin(x), color='#FF6B6B', linewidth=3, linestyle='-', marker='o', markersize=5, label='sin(x)')plt.plot(x, np.cos(x), color='#4ECDC4', linewidth=3, linestyle='--', marker='s', markersize=5, label='cos(x)')plt.title('自定义线条样式')plt.xlabel('x')plt.ylabel('y')plt.legend(fontsize=12)plt.grid(True, alpha=0.3, linestyle=':')plt.show()plt.figure(figsize=(10, 6))x = np.linspace(0, 10, 100)y = np.sin(x)plt.plot(x, y, color='blue', linewidth=2)# 找到最大值点max_idx = np.argmax(y)max_x = x[max_idx]max_y = y[max_idx]# 添加箭头注释plt.annotate('最大值', xy=(max_x, max_y), xytext=(max_x + 1, max_y + 0.5), arrowprops=dict(facecolor='red', shrink=0.05, width=2, headwidth=8), fontsize=12, ha='center')# 添加文本注释plt.text(2, 0.5, '这是一段文本注释', fontsize=12, bbox=dict(boxstyle='round,pad=0.5', facecolor='yellow', alpha=0.5))plt.title('添加注释')plt.xlabel('x')plt.ylabel('y')plt.grid(True, alpha=0.3)plt.show()我们有一份销售数据,包含以下字段:
import pandas as pdimport matplotlib.pyplot as pltimport numpy as np# 设置中文字体plt.rcParams["font.sans-serif"] = ["SimHei"]plt.rcParams["axes.unicode_minus"] = False# 创建模拟数据np.random.seed(42)dates = pd.date_range('2024-01-01', '2024-12-31', freq='D')products = ['智能手机', '笔记本电脑', '平板电脑', '耳机', '充电器']categories = ['电子产品', '电子产品', '电子产品', '配件', '配件']data = {'date': np.random.choice(dates, 1000),'product': np.random.choice(products, 1000),'category': np.random.choice(categories, 1000),'quantity': np.random.randint(1, 10, 1000),'price': np.random.choice([2999, 5999, 1999, 299, 99], 1000)}df = pd.DataFrame(data)df['revenue'] = df['quantity'] * df['price']# 1. 销售趋势分析daily_sales = df.groupby('date')['revenue'].sum().reset_index()plt.figure(figsize=(14, 6))plt.plot(daily_sales['date'], daily_sales['revenue'], color='#45B7D1', linewidth=1.5, alpha=0.7)plt.title('2024年每日销售趋势', fontsize=16)plt.xlabel('日期', fontsize=12)plt.ylabel('销售额', fontsize=12)plt.grid(True, alpha=0.3)plt.xticks(rotation=45)plt.tight_layout()plt.show()# 2. 产品类别销售分布category_sales = df.groupby('category')['revenue'].sum().sort_values(ascending=False)fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))# 柱状图colors = ['#FF6B6B', '#4ECDC4']bars = ax1.bar(category_sales.index, category_sales.values, color=colors, alpha=0.8)for bar in bars: height = bar.get_height() ax1.text(bar.get_x() + bar.get_width()/2., height,f'{height:,.0f}', ha='center', va='bottom', fontsize=11)ax1.set_title('不同类别的销售额', fontsize=14)ax1.set_ylabel('销售额', fontsize=12)# 饼图ax2.pie(category_sales.values, labels=category_sales.index, colors=colors, autopct='%1.1f%%', startangle=90)ax2.set_title('类别销售额占比', fontsize=14)ax2.axis('equal')plt.tight_layout()plt.show()# 3. 月度销售情况df['month'] = df['date'].dt.monthmonthly_sales = df.groupby('month')['revenue'].sum()plt.figure(figsize=(12, 6))months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']bars = plt.bar(months, monthly_sales.values, color='#96CEB4', alpha=0.8, edgecolor='black')# 添加数值标签for bar in bars: height = bar.get_height() plt.text(bar.get_x() + bar.get_width()/2., height,f'{height:,.0f}', ha='center', va='bottom', fontsize=10)plt.title('2024年月度销售额', fontsize=16)plt.xlabel('月份', fontsize=12)plt.ylabel('销售额', fontsize=12)plt.xticks(rotation=45)plt.grid(axis='y', alpha=0.3)plt.tight_layout()plt.show()Matplotlib是Python数据可视化的基础库,掌握Matplotlib可以让你灵活地创建各种类型的图表。通过本文的学习,你已经掌握了:
学习数据可视化的关键在于实践,多尝试不同的图表类型,多分析真实数据,才能真正掌握这项技能。
小贴士:数据可视化不仅仅是技术,更是一种艺术。好的可视化应该既美观又有效,能够清晰地传达数据背后的信息。