大数据分析与可视化 之 实验12 Matplotlib绘制图表(二)

发布时间 2023-12-30 20:20:29作者: Ivan丶c

实验12 Matplotlib绘制图表(二)

实验学时:2学时
实验类型:验证
实验要求:必修

一、实验目的

  1. 掌握Matplotlib的框架及图形属性。
  2. 掌握Matplotlib绘制图形的步骤。
  3. 掌握Matplotlib绘制柱形图、条形图、饼图、折线图。
  4. 掌握Matplotlib绘制散点图、等高线图、极坐标图、3D图。

二、实验要求

通过编程实现使用Matplotlib绘制柱形图、条形图、饼图、折线图、散点图、等高线图、极坐标图、3D图,并显示输出。

三、实验内容

任务1. 根据实验10任务1中的结果数据实现:
(1)用厦门市2018年1-6月白天和晚上都是晴天的天数、白天和晚上都是雨天的天数数据绘制对称柱形图
(2)用全年最高温和最低温均不超过10的天数、全年最高温超过30的天数、全年空气质量为优的天数、全年晴天天数、全年雨天天数数据绘制散点图。
(3)用每月雨天数占全年天数的比值绘制一个饼图。
用Python编写程序实现。

任务2.利用tushare模块导出2022年股票代码为“000001”的股票数据,按周汇总计算每周开盘价(monday_open)、收盘价(friday_close)、最高价(week_high)、最低价(week_low)。根据结果数据对开盘价(monday_open)、收盘价(friday_close)、最高价(week_high)、最低价(week_low)绘制折线图。用Python编写程序实现。

任务3. 利用如下等高线函数,绘制如下图所示的热力图。

def f(x, y):
    return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(- x ** 2 - y ** 2)


任务4. 利用如下函数,绘制如下图所示的3D曲面图。

def f(x,y):
return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)

test12.py

# encoding:utf-8
import numpy as np
import matplotlib as mpl
import matplotlib.pylab as plt
import pandas as pd
import tushare as ts
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.font_manager import FontProperties


def task1():
    mpl.rcParams['font.sans-serif'] = 'SimHei'
    mpl.rcParams['axes.unicode_minus'] = False
    # 读取CSV文件
    df = pd.read_csv("cleaned_xiamen_2018.csv", encoding="utf-8", parse_dates=['日期'], date_parser=lambda
        x: pd.to_datetime(x, format='%Y年%m月%d日'))

    # (1)对称柱形图
    sunny_days = df[(df['日期'].dt.month.isin([1, 2, 3, 4, 5, 6])) & (df['日间天气'] == '晴') & (df['夜间天气'] == '晴')]
    sunny_days_count = sunny_days.groupby(sunny_days['日期'].dt.month).size()
    rainy_days = df[(df['日期'].dt.month.isin([1, 2, 3, 4, 5, 6])) & (df['日间天气'] == '小雨') & (df['夜间天气'] == '小雨')]
    rainy_days_count = rainy_days.groupby(rainy_days['日期'].dt.month).size()
    # 确保两组数据长度相同
    sunny_days_count = sunny_days_count.reindex(range(1, 7), fill_value=0)
    rainy_days_count = rainy_days_count.reindex(range(1, 7), fill_value=0)
    fig, ax = plt.subplots()
    bar_locations = range(1, 7)
    ax.bar(bar_locations, sunny_days_count, label='晴天', color='gold')
    ax.bar(bar_locations, -rainy_days_count, label='雨天', color='lightblue')  # 注意这里取负值
    ax.set_xlabel('月份')
    ax.set_ylabel('天数')
    ax.set_title('1-6月份白天和晚上都是晴天/雨天的天数')
    ax.set_xticks(bar_locations)
    ax.set_xticklabels([f'Month {i}' for i in range(1, 7)])
    ax.legend()
    plt.show()

    # (2)散点图
    # 数据筛选
    temperature_condition = (df['当日最高温度'] <= 10) & (df['当日最低温度'] <= 10)
    high_temperature_condition = df['当日最高温度'] > 30
    air_quality_condition = df['质量等级'] == '优'
    sunny_days_condition = (df['日间天气'] == '晴') & (df['夜间天气'] == '晴')
    rainy_days_condition = (df['日间天气'] == '小雨') & (df['夜间天气'] == '小雨')
    # 统计数据
    temperature_days = df[temperature_condition]
    high_temperature_days = df[high_temperature_condition]
    air_quality_days = df[air_quality_condition]
    sunny_days = df[sunny_days_condition]
    rainy_days = df[rainy_days_condition]
    fig, ax = plt.subplots()
    ax.scatter(temperature_days['日期'], temperature_days['当日最高温度'], label='温度<=10°C', color='blue', marker='o')
    ax.scatter(high_temperature_days['日期'], high_temperature_days['当日最高温度'], label='最高温>30°C', color='red',
               marker='s')
    ax.scatter(air_quality_days['日期'], air_quality_days['当日最高温度'], label='空气质量优', color='green', marker='^')
    ax.scatter(sunny_days['日期'], sunny_days['当日最高温度'], label='晴天', color='orange', marker='d')
    ax.scatter(rainy_days['日期'], rainy_days['当日最高温度'], label='雨天', color='purple', marker='v')
    ax.set_xlabel('日期')
    ax.set_ylabel('最高温度')
    ax.set_title('全年天气情况散点图')
    ax.legend()
    plt.show()

    # (3)饼图
    monthly_rainy_days = df.groupby(df['日期'].dt.month)['日间天气'].apply(lambda x: x[x == '小雨'].count()).tolist()
    fig, ax = plt.subplots()
    labels = [f'第{i + 1}月' for i in range(len(monthly_rainy_days))]
    # 确保 monthly_rainy_days 和 labels 长度一致
    if len(monthly_rainy_days) == len(labels):
        ax.pie(monthly_rainy_days, labels=labels, autopct='%1.1f%%', startangle=90, colors=plt.cm.Paired.colors)
        ax.set_title('每月雨天数占全年比例')
        plt.show()
    else:
        print("错误:monthly_rainy_days 和 labels 的长度不一致。")


def shoupan(zgpa):
    spj = zgpa.set_index(zgpa.index)
    plt.plot(spj['close'])
    plt.title('中国平安每日收盘价')
    plt.show()


# 按周采样输出
def weeko(spj):
    spj_week = spj['close'].resample('W-MON').mean()
    print(spj_week.head(20))
    # 训练数据
    train_data = spj_week['2022': '2022']
    plt.plot(train_data)
    plt.title('股票周收盘价均值')
    plt.show()


def task2():
    mpl.rcParams['font.sans-serif'] = 'SimHei'
    mpl.rcParams['axes.unicode_minus'] = False
    zgpa = ts.get_hist_data('000001')
    zgpa.index = pd.to_datetime(zgpa.index)
    spj = zgpa.set_index(zgpa.index)
    fig = plt.figure(dpi=120, figsize=(5, 3))
    shoupan(zgpa)
    weeko(spj)


# 定义函数
def f(x, y):
    return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(- x ** 2 - y ** 2)


def task3():
    n = 256
    # 定义x,y
    x = np.linspace(-3, 3, n)
    y = np.linspace(-3, 3, n)
    # 生成网格数据
    X, Y = np.meshgrid(x, y)
    # 填充等高线的颜色,8是等高线分为几部分
    plt.contourf(X, Y, f(X, Y), 8, alpha=0.75, cmap=plt.cm.hot)  # cmap=plt.cm.hot映射为热力图
    # 绘制等高线
    C = plt.contour(X, Y, f(X, Y), 8, colors='black', linewidth=0.5)
    # 绘制等高线数据
    plt.clabel(C, inline=True, fontsize=10)
    # 去除坐标轴
    plt.xticks(())
    plt.yticks(())
    plt.show()


def task4():
    font = FontProperties(fname=None, size=14)
    font.set_family('SimHei')
    font.set_name('SimHei')
    font.set_style('normal')

    plt.rcParams['font.sans-serif'] = [font.get_name()]  # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

    n = 1000  # 1000*1000的点阵
    x, y = np.meshgrid(np.linspace(-3, 3, n), np.linspace(-3, 3, n))

    fig = plt.figure()
    plt.title('3D曲面图', fontdict={'size': 20, 'color': 'r'})
    ax = fig.add_subplot(111, projection='3d')  # 使用fig.gca方法也可以,但是需要指定projection='3d'参数
    ax.set_xlabel('x轴', fontdict={'size': 14, 'color': 'g'})
    ax.set_ylabel('y轴', fontdict={'size': 14, 'color': 'b'})
    ax.set_zlabel('z轴', fontdict={'size': 14, 'color': 'r'})
    ax.plot_surface(x, y, f(x, y), rstride=10, cstride=10, cmap='jet')
    plt.show()


if __name__ == '__main__':
    task1()
    task2()
    task3()
    task4()