爬虫说明:
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¶ms=t2:2020|t3:1|&limit=0,50
# 第二页
# https://ziliaoku.sports.qq.com/cube/index?cubeId=10&dimId=52&from=sportsdatabase&order=t70¶ms=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¶ms=t2:2020|t3:1|&limit={},{}"
# 球员1
# https://ziliaoku.sports.qq.com/cube/index?cubeId=8&dimId=5¶ms=t1:5009&from=sportsdatabase
# 球员2
# https://ziliaoku.sports.qq.com/cube/index?cubeId=8&dimId=5¶ms=t1:4244&from=sportsdatabase
# 通过url地址的比对 发现t1:后的为球员号码 其他不变
# 提取url共同部分当做详情页模板
self.detail_temp = "https://ziliaoku.sports.qq.com/cube/index?cubeId=8&dimId=5¶ms=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、项目的架构图为
代码展示
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()
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)
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
}
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
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()
__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())
主页简单创建了四个超链接指向对应的图表
<!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
<!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+'
'+'场均得分:'+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>
结论:
篮网球队的场均队员平均得分最高,遥遥领先其他球队,可见篮网的整体实力是很强的;而雷霆战队的场均队员平均得分最低,需要加油了。
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+'
'+'球员数量:'+res.value+'
'+'占比:'+res.percent+'%'
}else{
return '身高区间:'+res.name+'
'+'球员数量:'+res.value+'
'+'占比:'+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+'
'+'场均得分:'+res.value[0]+'
'+'场均上场时间:'+res.value[1]+
'
'+'场均盖帽:'+res.value[2]+'
'+'场均助攻:'+res.value[3]+'
'+'场均篮板:'+res.value[4]+
'
'+'场均三分命中率:'+(res.value[5]*1000/10).toFixed(1)+'%'+'
'+'场均罚球率:'+(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]+"
"+'场均得分:'+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项目代码链接