目錄
一、設計方案
二、項目背景
三、電影爬蟲
3.1 導入庫
3.2 發(fā)送請求
3.3 解析頁面
3.4 存儲到csv
四、數(shù)據(jù)持久化存儲
4.1 導入庫
4.2 存入MySQL
4.3 講解視頻
五、開發(fā)可視化大屏
5.1 柱形圖
5.2 餅圖
5.3 詞云圖
5.4 數(shù)據(jù)表格
5.5 漣漪散點圖
5.6 條形圖
5.7 大標題
5.8 Page組合
六、彩蛋-多種主題
6.1 CHALK主題
6.2 PURPLE主題
6.3 ESSOS主題
6.4 ROMANTIC主題
6.5 DARK主題?
七、拖拽演示視頻
八、講解視頻
“整篇文章較長,干貨很多!建議收藏后,分章節(jié)閱讀?!?/strong>
一、設計方案
整體設計方案思維導圖:?
整篇文章,也將按照這個結構來講解。
若有重點關注部分,可點擊章節(jié)目錄直接跳轉!
二、項目背景
針對某電影TOP250排行榜的數(shù)據(jù),開發(fā)一套可視化數(shù)據(jù)大屏系統(tǒng),展示各維度數(shù)據(jù)分析結果。
三、電影爬蟲
3.1 導入庫
import requests # 發(fā)送請求
from bs4 import BeautifulSoup # 解析網(wǎng)頁
import pandas as pd # 存取csv
from time import sleep # 等待時間
from sqlalchemy import create_engine # 連接數(shù)據(jù)庫
3.2 發(fā)送請求
定義一些空列表,用于臨時存儲爬取下的數(shù)據(jù)
movie_name = [] # 電影名稱
movie_url = [] # 電影鏈接
movie_star = [] # 電影評分
movie_star_people = [] # 評分人數(shù)
movie_director = [] # 導演
movie_actor = [] # 主演
movie_year = [] # 上映年份
movie_country = [] # 國家
movie_type = [] # 類型
short_comment = [] # 一句話短評
向頁面發(fā)送請求:
res = requests.get(url, headers=headers)
3.3 解析頁面
利用BeautifulSoup庫解析響應頁面:
soup = BeautifulSoup(res.text, 'html.parser')
用BeautifulSoup的select函數(shù),(css解析的方法)編寫代碼邏輯,部分核心代碼:
for movie in soup.select('.item'):
name = movie.select('.hd a')[0].text.replace('\n', '') # 電影名稱
movie_name.append(name)
url = movie.select('.hd a')[0]['href'] # 電影鏈接
movie_url.append(url)
star = movie.select('.rating_num')[0].text # 電影評分
movie_star.append(star)
star_people = movie.select('.star span')[3].text # 評分人數(shù)
star_people = star_people.strip().replace('人評價', '')
movie_star_people.append(star_people)
其中,需要說明的是,《大鬧天宮》這部電影和其他電影頁面排版不同:
它的上映年份有3個(其他電影只有1個上映年份),并且以"/"分隔,正好和國家、電影類型的分割線沖突,
所以,這里特殊處理一下:
if name == '大鬧天宮 / 大鬧天宮 上下集 / The Monkey King': # 大鬧天宮,特殊處理
year0 = movie_infos.split('\n')[1].split('/')[0].strip()
year1 = movie_infos.split('\n')[1].split('/')[1].strip()
year2 = movie_infos.split('\n')[1].split('/')[2].strip()
year = year0 + '/' + year1 + '/' + year2
movie_year.append(year)
country = movie_infos.split('\n')[1].split('/')[3].strip()
movie_country.append(country)
type = movie_infos.split('\n')[1].split('/')[4].strip()
movie_type.append(type)
3.4 存儲到csv
最后,將爬取到的數(shù)據(jù)保存到csv文件中:
def save_to_csv(csv_name):
"""
數(shù)據(jù)保存到csv
:return: None
"""
df = pd.DataFrame() # 初始化一個DataFrame對象
df['電影名稱'] = movie_name
df['電影鏈接'] = movie_url
df['電影評分'] = movie_star
df['評分人數(shù)'] = movie_star_people
df['導演'] = movie_director
df['主演'] = movie_actor
df['上映年份'] = movie_year
df['國家'] = movie_country
df['類型'] = movie_type
df.to_csv(csv_name, encoding='utf_8_sig') # 將數(shù)據(jù)保存到csv文件
四、數(shù)據(jù)持久化存儲
然后,就可以把csv數(shù)據(jù)導入到MySQL數(shù)據(jù)庫,做持久化存儲了。
4.1 導入庫
import pandas as pd # 存取csv
from sqlalchemy import create_engine # 連接數(shù)據(jù)庫
4.2 存入MySQL
最核心的三行代碼:
# 把csv導入mysql數(shù)據(jù)庫
engine = create_engine('mysql+pymysql://root:123456@localhost/db_bigscreen')
df = pd.read_csv('Movie250.csv')
df.to_sql(name='t_film', con=engine, chunksize=1000, if_exists='replace', index=None)
用create_engine創(chuàng)建數(shù)據(jù)庫連接,格式為:
create_engine('數(shù)據(jù)庫類型+數(shù)據(jù)庫驅(qū)動://用戶名:密碼@數(shù)據(jù)庫IP地址/數(shù)據(jù)庫名稱')
這樣,數(shù)據(jù)庫連接就創(chuàng)建好了。
然后,用pandas的read_csv函數(shù)讀取csv文件。
最后,用pandas的to_sql函數(shù),把數(shù)據(jù)存入MySQL數(shù)據(jù)庫:
name='college_t2' #mysql數(shù)據(jù)庫中的表名
con=engine # 數(shù)據(jù)庫連接
index=False #不包含索引字段
if_exists='replace' #如果表中存在數(shù)據(jù),就替換掉,另外,還支持append(追加數(shù)據(jù))
非常方便地完成了反向?qū)?,即:從csv向數(shù)據(jù)庫的導入。
4.3 講解視頻
同步講解視頻:
僅用Python三行代碼,實現(xiàn)數(shù)據(jù)庫和excel之間導入導出
五、開發(fā)可視化大屏
如文章開頭的思維導圖所說,首先把各個子圖表開發(fā)出來,然后用pyecharts的Page組件,把這些子圖表拼裝組合起來,形成大屏。
下面,依次講解每個子圖表的實現(xiàn)。
5.1 柱形圖
pyecharts官網(wǎng)-柱形圖: A Python Echarts Plotting Library built with love.
因為需要實現(xiàn)分段區(qū)間統(tǒng)計,所以先定義出一個區(qū)間對象:
# 設置分段
bins = [0, 100000, 200000, 300000, 500000, 1000000, 3000000]
# 設置標簽
labels = ['0-10w', '10w-20w', '20w-30w', '30w-50w', '50w-100w', '100w-300w']
然后,對數(shù)據(jù)進行按段切割,并統(tǒng)計個數(shù):
# 按分段離散化數(shù)據(jù)
segments = pd.cut(cmt_count_list, bins, labels=labels) # 按分段切割數(shù)據(jù)
counts = pd.value_counts(segments, sort=False).values.tolist() # 統(tǒng)計個數(shù)
最后,采用pyecharts里的Bar對象,畫出柱形圖:
bar = Bar(
init_opts=opts.InitOpts(theme=theme_config, width="450px", height="350px", chart_id='bar_cmt2')) # 初始化條形圖
bar.add_xaxis(labels, ) # 增加x軸數(shù)據(jù)
bar.add_yaxis("評價數(shù)", counts) # 增加y軸數(shù)據(jù)
bar.set_global_opts(
legend_opts=opts.LegendOpts(pos_left='right'),
title_opts=opts.TitleOpts(title="評價數(shù)量區(qū)間分布-柱形圖", pos_left='center'), # 標題
toolbox_opts=opts.ToolboxOpts(is_show=False, ), # 不顯示工具箱
xaxis_opts=opts.AxisOpts(name="評論數(shù)", # x軸名稱
axislabel_opts=opts.LabelOpts(font_size=8)), # 字體大小
yaxis_opts=opts.AxisOpts(name="電影數(shù)量",
axislabel_opts={"rotate": 0},
splitline_opts=opts.SplitLineOpts(is_show=True,
linestyle_opts=opts.LineStyleOpts(type_='solid')),
), # y軸名稱
)
# 標記最大值
bar.set_series_opts(
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max", name="最大值"), ],
symbol_size=35) # 標記符號大小
)
bar.render("評價數(shù)分布-柱形圖.html") # 生成html文件
print('生成完畢:評價數(shù)分布-柱形圖.html')
圖表效果:
5.2 餅圖
pyecharts官網(wǎng)-餅圖: A Python Echarts Plotting Library built with love.
繪制情感分布的餅圖。所以,首先要對評價數(shù)據(jù)進行情感分析。
鑒于電影評價內(nèi)容都是中文文本設計,情感分析采用snownlp技術進行。
score_list = [] # 情感評分值
tag_list = [] # 打標分類結果
pos_count = 0 # 計數(shù)器-積極
mid_count = 0 # 計數(shù)器-中性
neg_count = 0 # 計數(shù)器-消極
for comment in v_cmt_list:
tag = ''
sentiments_score = SnowNLP(comment).sentiments
if sentiments_score < 0.4: # 情感分小于0.4判定為消極
tag = '消極'
neg_count += 1
elif 0.4 <= sentiments_score <= 0.6: # 情感分在[0.4,0.6]直接判定為中性
tag = '中性'
mid_count += 1
else: # 情感分大于0.6判定為積極
tag = '積極'
pos_count += 1
score_list.append(sentiments_score) # 得分值
tag_list.append(tag) # 判定結果
df['情感得分'] = score_list
df['分析結果'] = tag_list
df.to_excel('情感判定結果.xlsx', index=None) # 把情感分析結果保存到excel文件
按照情感得分值劃分區(qū)間:
- 情感得分值小于0.4,判定為消極
- 情感得分值在0.4與0.6之間,判定為中性
- 情感得分值大于0.6,判定為積極
最終將結果保存到Excel文件中,查看下:
將此結果中的數(shù)據(jù),帶入到Pie組件中,畫出餅圖:
# 畫餅圖
pie = (
Pie(init_opts=opts.InitOpts(theme=theme_config, width="450px", height="350px", chart_id='pie1'))
.add(series_name="評價情感分布", # 系列名稱
data_pair=[['積極', pos_count], # 添加數(shù)據(jù)
['中性', mid_count],
['消極', neg_count]],
rosetype="radius", # 是否展示成南丁格爾圖
radius=["30%", "55%"], # 扇區(qū)圓心角展現(xiàn)數(shù)據(jù)的百分比,半徑展現(xiàn)數(shù)據(jù)的大小
) # 加入數(shù)據(jù)
.set_global_opts( # 全局設置項
title_opts=opts.TitleOpts(title="短評情感分布-餅圖", pos_left='center'), # 標題
legend_opts=opts.LegendOpts(pos_left='right', orient='vertical') # 圖例設置項,靠右,豎向排列
)
.set_series_opts(label_opts=opts.LabelOpts(formatter=": {c}"))) # 樣式設置項
pie.render('情感分布_餅圖.html') # 生成html文件
print('生成完畢:情感分布_餅圖.html')
圖表效果:
5.3 詞云圖
pyecharts官網(wǎng)-詞云圖: A Python Echarts Plotting Library built with love.
針對TOP250的電影名稱,繪制出詞云圖。
先對數(shù)據(jù)做清洗操作,然后直接畫出詞云圖即可:
wc = WordCloud(init_opts=opts.InitOpts(width="450px", height="350px", theme=theme_config, chart_id='wc1'))
wc.add(series_name="電影名稱",
data_pair=data,
word_size_range=[15, 20],
width='400px', # 寬度
height='300px', # 高度
word_gap=5 # 單詞間隔
) # 增加數(shù)據(jù)
wc.set_global_opts(
title_opts=opts.TitleOpts(pos_left='center',
title="電影名稱分析-詞云圖",
title_textstyle_opts=opts.TextStyleOpts(font_size=20) # 設置標題
),
tooltip_opts=opts.TooltipOpts(is_show=True), # 不顯示工具箱
)
wc.set_series_opts(label_opts=opts.LabelOpts(is_show=True))
wc.render('電影名稱_詞云圖.html') # 生成html文件
print('生成完畢:電影名稱_詞云圖.html')
圖表效果:
5.4 數(shù)據(jù)表格
pyecharts官網(wǎng)-表格: A Python Echarts Plotting Library built with love.
把排名前10的電影詳情數(shù)據(jù),展現(xiàn)到大屏上,采用pyecharts里的Table組件實現(xiàn)。
從MySQL數(shù)據(jù)庫讀取到數(shù)據(jù)后,直接進行繪制表格:
table = (
Table(page_title='我的表格標題', )
.add(headers=['排名', '電影名稱', '評分', '評論數(shù)', '上映年', '一句話短評'], rows=data_list, attributes={
"align": "left",
"border": False,
"padding": "20px",
"style": "background:{}; width:450px; height:350px; font-size:10px; color:#C0C0C0;padding:3px;".format(
table_color)
})
.set_global_opts(title_opts=opts.TitleOpts(title='這是表格1'))
)
table.render('電影排名TOP10_數(shù)據(jù)表格.html')
print('生成完畢:電影排名TOP10_數(shù)據(jù)表格.html')
圖表效果:
5.5 漣漪散點圖
pyecharts官網(wǎng)-漣漪散點圖: A Python Echarts Plotting Library built with love.
針對電影的上映年份和評分值,兩個緯度的數(shù)據(jù),繪制出漣漪散點圖(漣漪散點圖和普通散點圖的區(qū)別,就是漣漪散點圖是動態(tài)圖,圖上的每個點都在閃爍,像水面上的漣漪一樣)。
sc = (EffectScatter(init_opts=opts.InitOpts(width="450px", height="350px", theme=theme_config, chart_id='scatter1'))
.add_xaxis(xaxis_data=x_data)
.add_yaxis(
series_name="",
y_axis=y_data,
symbol_size=10,
label_opts=opts.LabelOpts(is_show=False),
)
.set_series_opts()
.set_global_opts(
# 忽略部分代碼
)
)
sc.render('評分年份分布-散點圖.html')
print('生成完畢:散點圖.html')
圖表效果(截圖是png,其實小圓點是在閃爍的):
??
5.6 條形圖
pyecharts官網(wǎng)-條形圖: A Python Echarts Plotting Library built with love.
針對評論數(shù)最多的10個電影的評論作者,繪制出橫向條形圖。
# 畫條形圖
bar = Bar(
init_opts=opts.InitOpts(theme=theme_config, width="450px", height="350px", chart_id='bar_cmt1')) # 初始化條形圖
bar.add_xaxis(x_data) # 增加x軸數(shù)據(jù)
bar.add_yaxis("評論數(shù)量", y_data) # 增加y軸數(shù)據(jù)
bar.reversal_axis() # 設置水平方向
bar.set_series_opts(label_opts=opts.LabelOpts(position="right")) # Label出現(xiàn)位置
bar.set_global_opts(
legend_opts=opts.LegendOpts(pos_left='right'),
title_opts=opts.TitleOpts(title="評論數(shù)TOP10作者-條形圖", pos_left='center'), # 標題
toolbox_opts=opts.ToolboxOpts(is_show=False, ), # 不顯示工具箱
xaxis_opts=opts.AxisOpts(name="評論", # x軸名稱
axislabel_opts=opts.LabelOpts(font_size=8, rotate=0),
splitline_opts=opts.SplitLineOpts(is_show=False)
),
yaxis_opts=opts.AxisOpts(name="電影", # y軸名稱
axislabel_opts=opts.LabelOpts(font_size=7, rotate=45), # y軸名稱
)
)
bar.render("評論數(shù)TOP10_條形圖.html") # 生成html文件
print('生成完畢:評論數(shù)TOP10_條形圖.html')
圖表效果:
5.7 大標題
由于pyecharts組件沒有專門用作標題的圖表,我決定靈活運用Table組件實現(xiàn)大標題。即,讓Table只有標題header,沒有數(shù)據(jù)行row,再針對header做一些樣式調(diào)整(字體增大等),即可實現(xiàn)一行大標題。
table = Table()
table.add(headers=[v_title], rows=[], attributes={
"align": "center",
"border": False,
"padding": "2px",
"style": "background:{}; width:1350px; height:50px; font-size:25px; color:#C0C0C0;".format(table_color)
})
table.render('大標題.html')
print('生成完畢:大標題.html')
圖表效果:
5.8 Page組合
最后,也是最關鍵的一步,把以上所有圖表組合到一起,用Page組件,并且選用DraggablePageLayout方法,即拖拽的方式,組合圖表:
# 繪制:整個頁面
page = Page(
page_title="基于Python的電影數(shù)據(jù)分析大屏",
layout=Page.DraggablePageLayout, # 拖拽方式
)
page.add(
# 增加:大標題
make_title(v_title='基于Python的電影數(shù)據(jù)分析大屏'),
# 繪制:中下方數(shù)據(jù)表格
make_table(v_df=df_table),
# 繪制:電影名稱詞云圖
filmname_wordcloud(v_str=film_all_list),
# 繪制:TOP10評論數(shù)-條形圖
make_top10_comment_bar(v_df=df),
# 繪制情感分布餅圖
make_analyse_pie(v_cmt_list=comment_all_list),
# 繪制:評價數(shù)分段統(tǒng)計-柱形圖
make_cmt_count_bar(v_df=df),
# 繪制:散點圖
make_scatter(x_data=year_list, y_data=score_list)
)
page.render('大屏_臨時.html') # 執(zhí)行完畢后,打開臨時html并排版,排版完點擊Save Config,把json文件放到本目錄下
print('生成完畢:大屏_臨時.html')
本代碼執(zhí)行完畢后,打開臨時html并排版,排版完點擊Save Config,把json文件放到本目錄下。
再執(zhí)行最后一步,調(diào)用json配置文件,生成最終大屏文件。
# 執(zhí)行之前,請確保:1、已經(jīng)把json文件放到本目錄下 2、把json中的title和table的id替換掉
Page.save_resize_html(
source="大屏_臨時.html",
cfg_file="chart_config.json",
dest="大屏_最終_0426.html"
)
拖拽過程的演示視頻:
【Python可視化大屏】用pyecharts拖拽生成大屏!
至此,所有代碼執(zhí)行完畢,生成了最終大屏html文件。
六、彩蛋-多種主題
為了實現(xiàn)不同顏色主題的大屏可視化效果,我開發(fā)了一個實現(xiàn)邏輯,只需修改一個參數(shù),即可展示不同顏色主題。
# 全局設置主題顏色
theme_config = ThemeType.CHALK # 顏色方案
由于Table組件是不能設置顏色主題的,所以我手寫了一個邏輯(用取色器獲取的RGB值,又轉成十六進制的顏色!),如下:
# 表格和標題的顏色
table_color = ""
if theme_config == ThemeType.DARK:
table_color = '#333333'
elif theme_config == ThemeType.CHALK:
table_color = '#293441'
elif theme_config == ThemeType.PURPLE_PASSION:
table_color = '#5B5C6E'
elif theme_config == ThemeType.ROMANTIC:
table_color = '#F0E8CD'
elif theme_config == ThemeType.ESSOS:
table_color = '#FDFCF5'
else:
table_color = ''
最終實現(xiàn)了多種顏色主題,包含以下。
6.1 CHALK主題
6.2 PURPLE主題
6.3 ESSOS主題
6.4 ROMANTIC主題
6.5 DARK主題?
通過5種主題顏色,展示同一個大屏效果,有被炫到嘛?
七、拖拽演示視頻
拖拽過程演示視頻:
【Python可視化大屏】用pyecharts拖拽生成大屏!
八、講解視頻
【Python大屏教程】全流程揭秘!講解可視化大屏背后原理
首發(fā)公眾號文章:【Python可視化大屏】全流程揭秘實現(xiàn)可視化數(shù)據(jù)大屏的背后原理!
我是馬哥,全網(wǎng)累計粉絲上萬,歡迎一起交流python技術。文章來源:http://www.zghlxwxcb.cn/news/detail-444975.html
各平臺搜索“馬哥python說”:知乎、嗶哩嗶哩、小紅書、新浪微博。文章來源地址http://www.zghlxwxcb.cn/news/detail-444975.html
到了這里,關于【Python可視化大屏】全流程講解pyecharts拖拽可視化大屏的背后原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!