Python爬虫实战+数据分析+数据可视化(NBA_腾讯体育)

一、爬虫部分

爬虫说明:
1、本爬虫是以面向对象的方式进行代码架构的
2、本爬虫爬取的数据存入到MongoDB数据库中
3、爬虫代码中有详细注释
4、博客末尾附有源码 源码中包含数据库文件和数据集文件

代码展示

import requests
import re
import json
from pymongo import MongoClient


class NBASpider():
    def __init__(self):
        self.headers = {
    
    
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36"
        }
        # 第一页
        # https://ziliaoku.sports.qq.com/cube/index?cubeId=10&dimId=52&from=sportsdatabase&order=t70&params=t2:2020|t3:1|&limit=0,50
        # 第二页
        # https://ziliaoku.sports.qq.com/cube/index?cubeId=10&dimId=52&from=sportsdatabase&order=t70&params=t2:2020|t3:1|&limit=50,50
        # 通过url地址的比对 发现只有limit参数的内容不同 并且limit是控制页面数据的参数 通过控制limit来控制翻页
        # 提取url共同部分当做列表页模板
        self.list_temp = "https://ziliaoku.sports.qq.com/cube/index?cubeId=10&dimId=52&from=sportsdatabase&order=t70&params=t2:2020|t3:1|&limit={},{}"
        # 球员1
        # https://ziliaoku.sports.qq.com/cube/index?cubeId=8&dimId=5&params=t1:5009&from=sportsdatabase
        # 球员2
        # https://ziliaoku.sports.qq.com/cube/index?cubeId=8&dimId=5&params=t1:4244&from=sportsdatabase
        # 通过url地址的比对 发现t1:后的为球员号码 其他不变
        # 提取url共同部分当做详情页模板
        self.detail_temp = "https://ziliaoku.sports.qq.com/cube/index?cubeId=8&dimId=5&params=t1:{}&from=sportsdatabase"
        self.client = MongoClient()
        self.collection = self.client['test']['nba']

    # 构造url请求地址
    def get_url_list(self):
        # 腾讯体育nba数据库有200名球员信息 每页显示50名球员信息 可以判断有4页
        url_list = [self.list_temp.format(i,50) for i in range(0,200,50)]
        return url_list

    # 发送请求
    def parse(self,url):
        rest = requests.get(url,headers=self.headers)
        return rest.content.decode()

    # 获取信息
    def get_content_list(self,str_html):
        json_html = json.loads(str_html)
        # 对响应数据进行分组
        nba_stars = json_html['data']['nbaPlayerSeasonStatRank']
        for i in nba_stars:
            item = {
    
    }
            item['号码'] = i['playerId']
            item['姓名'] = i['cnName']
            item['球队'] = i['teamName']
            item['场均得分'] = i['pointsPG']
            item['场均出手'] = i['fgAttemptedPG']
            item['场均命中率'] = i['fgPCT']
            item['场均犯规'] = i['foulsPG']
            item['场均三分出手'] = i['threesAttemptedPG']
            item['场均三分命中'] = i['threesPCT']
            item['场均上场时间'] = i['minutesPG']
            item['场次'] = i['gamesStarted']
            item['场均罚球'] = i['ftAttemptedPG']
            item['场均罚球率'] = i['ftPCT']
            item['场均盖帽'] = i['blocksPG']
            item['场均助攻'] = i['assistsPG']
            item['场均篮板'] = i['reboundsPG']
            # 请求球员详情数据
            self.parse_detail(self.detail_temp.format(item['号码']),item)

    # 获取球员详细信息 例如身高 体重 出生年月
    def parse_detail(self,url,item):
        rest = requests.get(url,headers=self.headers)
        json_html = json.loads(rest.content.decode())
        player_info = json_html['data']['playerBaseInfo']
        item['身高'] = player_info['height']
        item['体重'] = player_info['weight']
        item['身高'] = player_info['height']
        item['工资'] = player_info['wage']
        item['位置'] = player_info['position']
        item['出生日期'] = player_info['birthDate']
        print(item)
        self.save(item)

    # 保存信息
    def save(self,item):
        self.collection.insert(item)

    # 主方法
    def run(self):
        # 获取url地址
        url_list  = self.get_url_list()
        # 解析url地址
        for url in url_list:
            str_html = self.parse(url)
            self.get_content_list(str_html)

if __name__ == '__main__':
    nba = NBASpider()
    nba.run()

响应数据

  • 列表页
    在这里插入图片描述
  • 详情页
    在这里插入图片描述

二、数据分析和数据可视化部分

数据分析和数据可视化说明:
1、本博客通过Flask框架来进行数据分析和数据可视化
2、项目的架构图为
在这里插入图片描述

代码展示

  • 数据分析代码展示(analysis.py)
import re

from pymongo import MongoClient
import pandas as pd
import numpy as np
import pymysql

# 不同位置的球员数量占比
def pos_stars_count(df):
    # 处理位置的离散数据 中锋 中锋-前锋 前锋
    pos_series = df['位置'].str.split('-')
    pos_list = pos_series.tolist()
    # 将数据都放在一个数组中 再利用set方法的特性 去除重复数据 再转换成list数据
    pos_type_count = list(set([j for i in pos_list for j in i ]))
    # 构造0的矩阵
    zero_list = pd.DataFrame(np.zeros((df.shape[0],len(pos_type_count))),columns=pos_type_count)
    # 遍历0的矩阵 如果满足条件 则+1
    for i in range(len(zero_list)):
        zero_list.loc[i][pos_list[i]] = 1
    # 将每个列索引上的值累加
    pos_count = zero_list.sum().reset_index()
    # 构造列表嵌套列表的数据 方便后续mysql批量插入数据
    data = [[i['index'],int(i[0])] for i in pos_count.to_dict(orient="records")]
    print(data)
    return data

# 不同身高的球员数量占比
def height_stars_count(df):
    # 处理身高数据 193CM 去除CM
    df['身高'] = df['身高'].apply(lambda x:int(x.split('CM')[0]))
    # 对身高划分区间 分别为 180-190 190 190-200 200-210 210<
    # 将身高的数据类型转换成int
    df['身高'] = df['身高'].astype(np.int)
    # 首先添加身高区域列索引
    df['身高区间'] = ''
    # 通过循环操作 来划分区间
    for i in range(df.shape[0]):
        if df.loc[i]['身高']<190:
            df.loc[i,'身高区间'] = "<190"
        elif df.loc[i]['身高']>=190 and df.loc[i]['身高']<200:
            df.loc[i,'身高区间'] = "190-200"
        elif df.loc[i]['身高']>=200 and df.loc[i]['身高']<=210:
            df.loc[i,'身高区间'] = "200-210"
        elif df.loc[i]['身高']>210:
            df.loc[i,'身高区间'] = "210<"
    # 按照身高区域分组并进行统计
    grouped  = df.groupby('身高区间')['身高'].count().reset_index()
    # 构造列表嵌套列表的数据 方便后续mysql批量插入数据
    data = [[i['身高区间'],i['身高']] for i in grouped.to_dict(orient="records")]
    print(data)
    return data

# nba球员的年龄与场均得分的关系
def age_stars_count(df):
    # 数据中只有出生日期没有球员年龄 因此需要构造年龄数据
    # 将时间字符串转换成pandas时间类型
    df['出生日期'] = pd.to_datetime(df['出生日期'])
    # 再将pandas时间类型转换成DateTimeIndex类型
    date = pd.DatetimeIndex(df['出生日期'])
    # 取出具体的年 作为列索引填充数据
    df['year'] = date.year
    # 球员年龄 = 当前年份 - 出生年份
    df['年龄'] = df['year'].apply(lambda x:2021-int(x))
    # 构造列表嵌套元组的数据 方便后续mysql批量插入数据
    age = df['年龄'].sort_values().tolist()
    score = df['场均得分'].apply(lambda x:round(float(x),1)).tolist()
    data = list(zip(age,score))
    print(data)
    return data

# 统计不同球队的场均平均得分
def team_stars_score(df):
    # 按照球队进行分组 并统计每个球队球员的场均平均得分
    # 统计每队球员数量
    num_grouped = df.groupby('球队')['号码'].count()
    # 统计每队场均总得分
    # 由于 场均得分的数据为字符串数据 因此需要转换数据类型 进行累加
    df['场均得分'] = df['场均得分'].astype(np.float)
    score_grouped2 = df.groupby('球队')['场均得分'].sum()
    # 计算每个球队球员的场均平均得分
    avg_score = (score_grouped2/num_grouped).reset_index()
    # 对avg_score重新设置索引并修改列索引
    avg_score.columns = ['球队','球队场均平均得分']
    # 对球队场均平均得分数据进行处理 保留一位小数
    avg_score['球队场均平均得分'] = avg_score['球队场均平均得分'].apply(lambda x:round(x,1))
    # 构造列表嵌套列表的数据 方便后续mysql批量插入数据
    data = [[i['球队'],i['球队场均平均得分']] for i in avg_score.to_dict(orient="records")]
    print(data)
    return data

# 对比我最喜欢的三个nba球星数据 詹姆斯 库里 杜兰特
def enjoy_stars_compare(df):
    # 获取数据
    zms = df[df['姓名']=="勒布朗-詹姆斯"]
    kl = df[df['姓名']=="斯蒂芬-库里"]
    dlt = df[df['姓名']=="凯文-杜兰特"]
    # 拼接数据
    my_enjoy_stars = pd.concat([zms,kl,dlt],axis=0)
    # 比较参数 场均得分 场均上场时间 场均三分命中 场均盖帽 场均助攻 场均篮板 场均罚球率
    data = [[i['姓名'],i['场均得分'],i['场均上场时间'],i['场均三分命中'],i['场均盖帽'],i['场均助攻'],i['场均篮板'],i['场均罚球率']] for i in my_enjoy_stars.to_dict(orient="records")]
    print(data)
    return data

if __name__ == '__main__':
    # 初始化mongodb连接
    client = MongoClient()
    collection = client['test']['nba']
    # 获取数据
    nba_stars = collection.find({
    
    },{
    
    '_id':0})
    # 将数据转换成dataFrame类型
    df = pd.DataFrame(nba_stars)
    # 打印基本信息
    print(df.info())
    print(df.head(5))

    # 不同位置的球员数量占比
    # data = pos_stars_count(df)

    # 不同身高的球员数量占比
    # data =  height_stars_count(df)

    # nba球员的年龄与得分的关系
    # data = age_stars_count(df)

    # 统计不同球队的场均平均得分
    # data = team_stars_score(df)

    # 对比我最喜欢的三个nba球星数据 詹姆斯 库里 杜兰特
    data = enjoy_stars_compare(df)

    # 初始化mysql数据库连接
    conn = pymysql.Connect(host="localhost",user="root",password="123456",port=3306,database="nba",charset="utf8")
    with conn.cursor() as cursor:
        # 不同位置的球员数量占比
        # sql = "insert into db_pos_stars_count(pos,count) values(%s,%s)"
        # 不同身高的球员数量占比
        # sql = "insert into db_height_stars_count(height_area,count) values(%s,%s)"
        # nba球员的年龄与得分的关系
        # sql = "insert into db_age_stars_score(age,score) values(%s,%s)"
        # 统计不同球队的场均平均得分
        # sql = "insert into db_team_stars_score(team,score) values(%s,%s)"
        # 对比我最喜欢的三个nba球星数据 詹姆斯 库里 杜兰特
        sql = "insert into db_enjoy_stars_compare(name,score,time,three_rate,block,assists,backboard,penalty) values(%s,%s,%s,%s,%s,%s,%s,%s)"
        try:
            result = cursor.executemany(sql,data)
            if result:
                print('插入成功')
                conn.commit()
        except pymysql.MySQLError as err:
            print(err)
            conn.rollback()
        finally:
            conn.close()

  • 数据库模型文件展示(models.py)
from api_1_0 import db

# 不同位置的球员数量模型
class PosStarsCount(db.Model):
    __tablename__ = "db_pos_stars_count"
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    pos = db.Column(db.String(64),nullable=False)
    count = db.Column(db.Integer,nullable=False)


# 不同身高的球员数量占比
class HeightStarsCount(db.Model):
    __tablename__ = "db_height_stars_count"
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    height_area = db.Column(db.String(64),nullable=False)
    count = db.Column(db.Integer,nullable=False)

# nba球员的年龄与场均得分的关系
class AgeStarsScore(db.Model):
    __tablename__ = "db_age_stars_score"
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    age = db.Column(db.Integer,nullable=False)
    score = db.Column(db.Float,nullable=False)

# 统计不同球队的场均平均得分
class TeamStarsScore(db.Model):
    __tablename__ = "db_team_stars_score"
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    team = db.Column(db.String(64),nullable=False)
    score = db.Column(db.Float,nullable=False)

# 对比我最喜欢的三个nba球星数据 詹姆斯 库里 杜兰特
class enjoyStarsCompare(db.Model):
    __tablename__ = "db_enjoy_stars_compare"
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    name = db.Column(db.String(64),nullable=False)
    score = db.Column(db.String(64),nullable=False)
    time = db.Column(db.String(64),nullable=False)
    three_rate = db.Column(db.String(64),nullable=False)
    block = db.Column(db.String(64),nullable=False)
    assists  = db.Column(db.String(64),nullable=False)
    backboard = db.Column(db.String(64),nullable=False)
    penalty = db.Column(db.String(64),nullable=False)
  • 配置文件代码展示(config.py)
class Config(object):
    SECRET_KEY = 'msqdyq1314'
    SQLALCHEMY_DATABASE_URI = 'mysql://root:123456@localhost:3306/nba'
    SQLALCHEMY_TRACK_MODIFICATIONS = True

class DevelopmentConfig(Config):
    DEBUG = True

class ProjectConfig(Config):
    pass


config_map = {
    
    
    'develop':DevelopmentConfig,
    'project':ProjectConfig
}
  • 主工程目录代码展示(api_1_0/_init_.py)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config_map
import pymysql
pymysql.install_as_MySQLdb()

db = SQLAlchemy()

def create_app(mode='develop'):
    # 创建app实例对象对象
    app = Flask(__name__)
    config_name = config_map[mode]
    print(config_name)
    app.config.from_object(config_name)

    # 加载数据库实例
    db.init_app(app)

    # 注册蓝图
    from api_1_0 import view
    app.register_blueprint(view.blue,url_prefix="/show")
    return app

  • 主程序文件代码展示(manager.py)
from api_1_0 import create_app,db
from flask_script import Manager
from flask_migrate import Migrate,MigrateCommand
from flask import render_template

app = create_app()
# 开启命令行运行程序
manager = Manager(app)
# 初始化数据库迁移库
Migrate(app,db)
# 添加命令行命令
manager.add_command('db',MigrateCommand)

# 首页
@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    manager.run()

  • 视图文件代码展示(api_1_0/views/_init_.py,show.py)

__init__.py

from flask import Blueprint
# 让主程序在执行的时候知道数据库模型的存在
from api_1_0 import models

blue = Blueprint('show',__name__)

from . import show

show.py

import re
from . import blue
from api_1_0.models import AgeStarsScore,enjoyStarsCompare,HeightStarsCount,PosStarsCount,TeamStarsScore
from flask import render_template
import pandas as pd
import numpy as np

# NBA不同位置的球员数量占比&NBA不同身高的球员数量占比
@blue.route('/drawPie')
def drawPie():
    pos_stars_count = PosStarsCount.query.all()
    height_stars_count = HeightStarsCount.query.all()
    # 将数据转换成列表嵌套字典类型数据 方便饼图数据渲染
    data1 = [{
    
    'name':i.pos,'value':i.count} for i in pos_stars_count]
    data2 = [{
    
    'name':i.height_area,'value':i.count} for i in height_stars_count]
    return render_template('drawPie.html',**locals())

# NBA球员的年龄与得分的关系散点图
@blue.route('/drawScatter')
def drawScatter():
    age_stars_score = AgeStarsScore.query.all()
    # 将数据转换成列表嵌套列表类型数据 方便散点图数据渲染
    data = [[i.age,i.score]  for i in age_stars_score]
    return render_template('drawScatter.html',**locals())

# NBA不同球队的场均平均得分柱状图
@blue.route('/drawBar')
def drawBar():
    team_stars_score = TeamStarsScore.query.all()
    # 将数据转换成两个列表类型数据 方便柱状图数据渲染
    team = [i.team for i in team_stars_score]
    score = [i.score for i in team_stars_score]
    print(team,score)
    return render_template('drawBar.html',**locals())

# 詹姆斯、库里、杜兰特NBA数据对比雷达图
@blue.route('/drawRadar')
def drawRadar():
    enjoy_stars_com = enjoyStarsCompare.query.all()
    data = [{
    
    '姓名':i.name,'场均得分':i.score,
             '场均上场时间':i.time,'场均盖帽':i.block,
             '场均助攻':i.assists,'场均篮板':i.backboard,'场均三分命中率':i.three_rate,'场均罚球率':i.penalty} for i in enjoy_stars_com]
    # 将数据转换成dataFrame类型
    df = pd.DataFrame(data,dtype=np.float)
    max_data = df.max()[1:]
    # 构造雷达图的indicator 将场均三分命中率 场均罚球率先排除出来 因为概率的最大值是为1 所以要另外处理
    # 为了让雷达图更加美观 将最大值在原有的基础上加上原有值的十分之一
    indicator = [{
    
    'name':k,'max':float(v)+float(v/10)} for k,v in max_data.to_dict().items() if not len(re.findall('率',k))>0]
    indicator.append({
    
    'name':'场均三分命中率','max':1})
    indicator.append({
    
    'name':'场均罚球率','max':1})
    print(df)
    # 分别去除三位球星的数据 不要姓名
    zms = df.loc[0][1:].tolist()
    kl = df.loc[1][1:].tolist()
    dlt = df.loc[2][1:].tolist()
    return render_template('drawRadar.html',**locals())

  • 主页展示(index.html)

主页简单创建了四个超链接指向对应的图表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页说明</title>
    <style>
        .container{
    
    
            width: 100%;
            height: 600px;
            padding: 40px;
            line-height: 60px;
        }
        ul{
    
    
            margin: auto;
            width: 60%;
        }
    </style>
</head>
<body>
    <div class="container">
        <ul>
            <li><a href="http://127.0.0.1:5000/show/drawPie" target="_blank"><h3>NBA不同位置的球员数量占比&NBA不同身高的球员数量占比</h3></a></li>
            <li><a href="http://127.0.0.1:5000/show/drawScatter" target="_blank"><h3>NBA球员的年龄与得分的关系散点图</h3></a></li>
            <li><a href="http://127.0.0.1:5000/show/drawBar" target="_blank"><h3>NBA不同球队的场均平均得分柱状图</h3></a></li>
            <li><a href="http://127.0.0.1:5000/show/drawRadar" target="_blank"><h3>詹姆斯、库里、杜兰特NBA数据对比雷达图</h3></a></li>
        </ul>
    </div>
</body>
</html>

在这里插入图片描述

  • 模板文件代码展示(drawBar.html,drawPie.html,drawRadar.html,drawScatter.html)

drawBar.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>NBA不同球队的场均平均得分柱状图</title>
    <script src="../static/js/echarts.min.js"></script>
    <script src="../static/theme/vintage.js"></script>
</head>
<body>
<div class="cart" style="width: 1600px;height: 600px;margin: auto"></div>
<script>
    var myCharts = echarts.init(document.querySelector('.cart'),'vintage')
    var team = {
    
    {
    
     team|tojson }}
    var score = {
    
    {
    
     score|tojson }}
    var option = {
    
    
        title:{
    
    
            text:"NBA不同球队的场均平均得分",
            textStyle:{
    
    
                fontFamily:'楷体',
                fontSize:21
            },
            left:10,
            top:10
        },
        xAxis:{
    
    
            type:'category',
            data:team,
            axisLabel:{
    
    
                interval:0,
                margin:10,
                rotate:40
            }
        },
        yAxis:{
    
    
            type:'value'
        },
        legend:{
    
    
            name:['场均得分']
        },
        tooltip:{
    
    
            trigger:'item',
            triggerOn:'mousemove',
            formatter:function (res)
            {
    
    
                return '球队:'+res.name+'<br>'+'场均得分:'+res.value
            }
        },
        series:[
            {
    
    
                type:'bar',
                name:'场均得分',
                data:score,
                label:{
    
    
                    show:true,
                    position:'top',
                    rotate:40,
                    distance:10
                },
                markPoint:{
    
    
                    data:[
                        {
    
    
                            type:'max',
                            name:'最大值',
                            label:{
    
    
                                show: true,
                                formatter:function (res)
                                {
    
    
                                    return res.name
                                }
                            },
                            symbolSize:[40,40],
                            symbolOffset:[0,-25]
                        },
                        {
    
    
                            type:'min',
                            name:'最小值',
                            label:{
    
    
                                show: true,
                                formatter:function (res)
                                {
    
    
                                    return res.name
                                }
                            },
                            symbolSize:[40,40],
                            symbolOffset:[0,-25]
                        }
                    ]
                }
            }
        ]
    }
    myCharts.setOption(option)
</script>
</body>
</html>

在这里插入图片描述

扫描二维码关注公众号,回复: 13786588 查看本文章

结论:
篮网球队的场均队员平均得分最高,遥遥领先其他球队,可见篮网的整体实力是很强的;而雷霆战队的场均队员平均得分最低,需要加油了。

drawPie.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>NBA不同位置的球员数量占比&NBA不同身高的球员数量占比</title>
    <script src="../static/js/echarts.min.js"></script>
    <script src="../static/theme/vintage.js"></script>
    <style>
        .cart_group{
    
    
            padding: 60px;
            display: flex;
            justify-content: space-between;
        }
        .cart1{
    
    
            width: 700px;
            height: 500px;
        }
        .cart2{
    
    
            width: 700px;
            height: 500px;
        }
    </style>
</head>
<body>
<div class="cart_group">
    <div class="cart1"></div>
    <div class="cart2"></div>
</div>
<script>
    var myCharts1 = echarts.init(document.querySelector('.cart1'),'vintage')
    var myCharts2 = echarts.init(document.querySelector('.cart2'),'vintage')
    var data1 = {
    
    {
    
     data1|tojson }}
    var data2 = {
    
    {
    
     data2|tojson }}

    function getOption(data,title_text,name_text){
    
    
        var option = {
    
    
            title:{
    
    
                text:title_text,
                textStyle:{
    
    
                    fontFamily:'楷体',
                    fontSize:21,
                },
                top:10,
                left:10
            },
            legend:{
    
    
              name:  ['球员数量'],
                bottom:15,
                left: 15,
                orient:'vertical'
            },
            tooltip:{
    
    
                trigger:'item',
                triggerOn:'mmousemove',
                formatter:function (res)
                {
    
    
                    if(res.seriesName=="位置:球员数量")
                    {
    
    
                        return '位置:'+res.name+'<br>'+'球员数量:'+res.value+'<br>'+'占比:'+res.percent+'%'
                    }else{
    
    
                        return '身高区间:'+res.name+'<br>'+'球员数量:'+res.value+'<br>'+'占比:'+res.percent+'%'
                    }
                }
            },
            series:[
                {
    
    
                    type:'pie',
                    name:name_text,
                    data:data,
                    label:{
    
    
                        show:true,
                    },
                    {
    
    #radius:['50%','70%'], //环形饼图#}
                    roseType:'radius', //南丁格尔玫瑰图
                    selectedMode:'multiple',
                    selectedOffset:20
                }
            ]
        }
        return option
    }
    {
    
    #NBA不同位置的球员数量占比#}
    var option1 = getOption(data1,'NBA不同位置的球员数量占比','位置:球员数量')
    {
    
    #NBA不同身高的球员数量占比#}
    var option2 = getOption(data2,'NBA不同身高的球员数量占比','身高:球员数量')

    myCharts1.setOption(option1)
    myCharts2.setOption(option2)
</script>
</body>
</html>

在这里插入图片描述

结论:
前锋和后卫的球员数量占比明显,可见这两个位置对于整个球队的重要程度是比较大的;NBA球员的身高普遍在190-210之间,果然打篮球还是需要个子高的,随便拉出来都是个巨人的存在。

drawRadar.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>詹姆斯、库里、杜兰特NBA数据对比雷达图</title>
    <script src="../static/js/echarts.min.js"></script>
    <script src="../static/theme/vintage.js"></script>
</head>
<body>
<div class="cart" style="width: 1000px;height: 600px;margin: auto"></div>
<script>
    var myCharts = echarts.init(document.querySelector('.cart'),'vintage')
    var indicator_data = {
    
    {
    
     indicator|tojson }}
    var zms = {
    
    {
    
     zms|tojson }}
    var kl = {
    
    {
    
     kl|tojson }}
    var dlt = {
    
    {
    
     dlt|tojson }}
    var option = {
    
    
        title:{
    
    
            text:"詹姆斯、库里、杜兰特NBA数据对比",
            textStyle:{
    
    
                fontFamily:'楷体',
                fontSize:21
            },
            top: 10,
            left:10
        },
        radar:{
    
    
            indicator:indicator_data,
            shape:'polygon'
        },
        legend:{
    
    
            name:['詹姆斯','库里','杜兰特'],
            top: 10
        },
        tooltip:{
    
    
            trigger:'item',
            triggerOn:'mousemove',
            formatter:function(res)
            {
    
    
                return '姓名:'+res.name+'<br>'+'场均得分:'+res.value[0]+'<br>'+'场均上场时间:'+res.value[1]+
                    '<br>'+'场均盖帽:'+res.value[2]+'<br>'+'场均助攻:'+res.value[3]+'<br>'+'场均篮板:'+res.value[4]+
                    '<br>'+'场均三分命中率:'+(res.value[5]*1000/10).toFixed(1)+'%'+'<br>'+'场均罚球率:'+(res.value[6]*1000/10).toFixed(1)+'%'
            }
        },
        series:[
            {
    
    
                type:'radar',
                data:[
                    {
    
    
                        name:'詹姆斯',
                        value: zms
                    },
                    {
    
    
                        name:'库里',
                        value: kl
                    },
                    {
    
    
                        name:'杜兰特',
                        value: dlt
                    }
                ]
            }
        ]
    }
    myCharts.setOption(option)
</script>
</body>
</html>

在这里插入图片描述

结论:
整体来看杜兰特的综合实力较强,相当于一名输出战士,场均得分也是最高的;库里的场均罚球率最高,篮板和场均盖帽最低,相当于一个没有输出的法师;詹姆斯的场均助攻和篮板最高,其他数据都很中规中矩,相当于一名能carry的辅助。

drawScatter.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>NBA球员的年龄与得分的关系散点图</title>
    <script src="../static/js/echarts.min.js"></script>
    <script src="../static/theme/vintage.js"></script>
</head>
<body>
<div class="cart" style="width: 900px;height: 600px;margin: auto"></div>
<script>
    var myCharts = echarts.init(document.querySelector('.cart'),'vintage')
    var data = {
    
    {
    
     data|tojson }}
    var option = {
    
    
        title:{
    
    
            text:'NBA球员的年龄与得分的关系',
            textStyle:{
    
    
                fontFamily:'楷体',
                fontSize:21
            },
            top:10,
            left:10
        },
        tooltip:{
    
    
            trigger:'item',
            triggerOn:'mousemove',
            formatter:function(res){
    
    
                return '年龄:'+res.value[0]+"<br>"+'场均得分:'+res.value[1].toFixed(1)
            }
        },
        legend:{
    
    
            name:['年龄-得分'],
            top: 10,
            textStyle: {
    
    
                fontSize: 14
            }
        },
        xAxis:{
    
    
            type:'value',
            scale: true,
            name:'年龄',
            nameLocation:'middle',
             nameTextStyle:{
    
    
                fontSize:16,
                 padding:10
            }
        },
        yAxis:{
    
    
            type:'value',
            scale:true,
            name:'得分',
            nameLocation:'middle',
            nameTextStyle:{
    
    
                fontSize:16,
                padding:15
            }
        },
        series:[
            {
    
    
                name:'年龄-得分',
                type:'effectScatter',
                showEffectOn:'emphasis',
                rippleEffect:{
    
    
                    scale:10
                },
                data:data,
            }
        ]
    }
    myCharts.setOption(option)
</script>
</body>
</html>

在这里插入图片描述

结论:
NBA球员的年龄与场均得分呈负相关,球员的年龄越大,场均得分越高,看来真的是人老了力不从心了,长江后浪推前浪,一浪跟比一浪强啊。

以下是项目源码,希望能够帮助你们,如有疑问,下方评论
flask项目代码链接

猜你喜欢

转载自blog.csdn.net/qq_45821420/article/details/113485505