一、動態條形圖
首先,不妨猜想一下這個是如何實作的,影片即是一幀一幀靜態畫面的連續播放,所以我們只需要將每一天都畫一次圖,再拼成 GIF 即可,
如下為第一天和最后一天的條形圖:
再來看一下用于畫圖的每日資料,假設2020年1月1日為起始日期,1月20日為當天(即發布供檢閱的)日期,故要對這些資料畫20次圖(別怕,兄dei),
進入代碼環節:先按需求讀取資料(讀表最愛的 pandas 庫又出現啦),為了便于處理日期,將 excel 中的日期一列的值轉為字串格式,再利用 datatime 將起始日期設為時間戳格式,
import pandas as pd
import datetime
df = pd.read_excel("資料.xlsx")
df['日期文本'] = df['日期'].apply(lambda x: str(x)[:10])
t = datetime.datetime(2020,1,1) # 起始日期
選擇 matplotlib 庫進行繪圖:先設定畫布,回傳模型和畫圖物件,接著不要忘記設定字體以避免中文顯示例外,因為有3個專案需要區分上色,因此再創建一個顏色串列,可以自行百度喜歡的顏色代碼,
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10,6)) # 畫布
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 字體設為微軟雅黑
colors = ['#ADD8E6', '#DC143C', '#FFC0CB'] # 顏色串列
撰寫繪圖函式:傳入的引數是對于起始日期所經過的天數,通過 t + datetime.timedelta(days=date) 計算需要繪制的指定天數的日期,再利用 strftime("%Y-%m-%d") 將其還原為日期文本,然后通過該日期文本取出當天的資料存入新的 df_ 中,下一步即為通過 barh 方法繪制條形圖,且每次畫新圖前需清空上一次的影像,
def draw(date):
# 資料處理 ------
current_date = (t + datetime.timedelta(days=date)).strftime("%Y-%m-%d")
df_ = df[df['日期文本'].eq(current_date)]
days = df_['天數']
item = df_["專案"]
# 繪制條形圖 ------
ax.clear() # 重繪
# for i in range(1,len(itme.uni))
ax.barh(item, days, color = colors)
如此之后,呼叫 draw(19) 來畫出經過19天后,也就是第20天的影像,通過 plt.show() 臨時查看一下,
和最終效果圖還有一定的差距,多了坐標軸標簽,少了系列標簽、資料標注和右上角的滾動時間,繼續完善 draw 函式:
for y, (x,name) in enumerate(zip(days.values,item.values)): # 系列標注
ax.text(x, y, "%s" % x, size=12)
if x > 1:
ax.text(x-0.5, y, name, size=14, ha = 'right')
ax.text(1, 1.01, current_date, transform = ax.transAxes, size= 20, ha='right') # 滾動時間
ax.get_xaxis().set_visible(False) # 隱藏坐標軸
ax.get_yaxis().set_visible(False)
接下來就是用 for 回圈畫出20張圖并通過 plt.savefig('xxx.png') 一一保存,再使用 imageio 庫或其他影像工具來合成 gif 啦!
(不不不,慢著慢著)如果真要這樣做就太麻煩了,下面該祭出這次的主角了!
import matplotlib.animation as ani
matplotlib 庫提供了動態繪圖的模塊,可以幫助我們更加輕松的制作 gif,只需傳入模型、繪圖函式、和一個 int 型別的串列即可,因此最初設計 draw 函式時所需的引數是天數 date,interval 引數為繪制每張圖的時間間隔,用于在 plt.show() 中檢查效果,最終保存 gif 影像時可以通過 fps 引數設定幀數,
timeSlot = [x for x in range(0,20)] # 時間軸
animator = ani.FuncAnimation(fig, draw, frames=timeSlot ,interval = 100)
animator.save('test.gif',fps=10)
附完整代碼:
import matplotlib.pyplot as plt
import matplotlib.animation as ani
import pandas as pd
import datetime
df = pd.read_excel("資料.xlsx")
df['日期文本'] = df['日期'].apply(lambda x: str(x)[:10])
t = datetime.datetime(2020,1,1) # 起始日期
fig, ax = plt.subplots(figsize=(10,6)) # 畫布
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 字體設為微軟雅黑
timeSlot = [x for x in range(0,20)] # 時間軸
colors = ['#ADD8E6', '#DC143C', '#FFC0CB'] # 顏色串列
def draw(date):
print(date)
# 資料處理 ------
current_date = (t + datetime.timedelta(days=date)).strftime("%Y-%m-%d")
df_ = df[df['日期文本'].eq(current_date)]
days = df_['天數']
item = df_["專案"]
# 繪制條形圖 ------
ax.clear() # 重繪
ax.barh(item, days, color = colors)
for y, (x,name) in enumerate(zip(days.values,item.values)): # 系列標注
ax.text(x, y, "%s" % x, size=12)
if x > 1:
ax.text(x-0.5, y, name, size=14, ha = 'right')
ax.text(1, 1.01, current_date, transform = ax.transAxes, size= 20, ha='right') # 滾動時間
ax.get_xaxis().set_visible(False) # 隱藏坐標軸
ax.get_yaxis().set_visible(False)
# draw(19)
# plt.savefig('test.png')
animator = ani.FuncAnimation(fig, draw, frames=timeSlot ,interval = 100) # interval時間間隔
plt.show()
# animator.save('test.gif',fps=10)
二、定制二維碼
不解釋!(看注釋)直接上代碼:
from MyQR import myqr # 需先安裝MyQR庫
def QR_myqr():
myqr.run(
'https://', # 二維碼指向鏈接,或無格式文本(但不支持中文)
version = 5, # 大小1~40
level='H', # 糾錯級別
picture = 'img.jpg', # 底圖路徑
colorized = True, # 彩色
contrast = 1.0, # 對比度
brightness = 1.0, # 亮度
save_name = 'save.jpg', # 保存檔案名
save_dir = 'D:/' #保存目錄
)
三、撰寫靜態html頁面
如果需要通過二維碼來訪問你的網站,那就需要先將其部署到服務器,方法也是多種多樣的,比如某企鵝云,個人用戶有6個月的免費時長,我們在這里要介紹的是 github(其實是因為我公司的電腦不能上外網,測驗的時候用不了企鵝云才用的 github,國內手機訪問還是放在國內的服務器比較快,大概是的)
(嗯?就算你問上不了外網卻能上 github 我也…大概是限制的網段沒覆寫到吧哈哈)
(嗯?我在公司劃水的事情暴露了嗎),
不過在那之前,先把本地的 html 寫好吧!
通過開頭的最終(不是最終的)效果圖可以發現,gif 是首尾相接回圈播放的,那最后一天的影像一下子閃過去就看不清楚了,可以修改一下傳入的時間序列,把最后一幅圖再畫多幾遍,就有停留的效果了,為了更好地展現效果,下面的圖中所用資料的時間周期改為了從6月1日到8月25日(七夕),經過了86天,并增加了兩條專案,
timeSlot = [x for x in range(0,86)]+[85]*15
直接放進 html 頁面里,就單單一張圖好像還缺了點什么,那就跟隨動圖的節奏在下方列印文字吧,首先設定兩個 div 的樣式,一個用于展示 gif,一個用于列印文字:
<head>
<style>
.process_gif{ /*顯示動態barh*/
background-image:url("./process.gif");
background-repeat: no-repeat;
background-size: cover;
margin:0 auto;
width: 370px;
height: 220px;
position: relative;
z-index: 1;
}
.show_txt{ /*顯示文字*/
margin:0 auto;
background-color: azure;
width: 370px;
height: 200px;
position: relative;
text-align: center;
padding-top: 10px;
z-index: 1;
}
</style>
</head>
然后在 body 里讓它們顯示出來:
<body>
<div class="process_gif" id="process"></div>
<div class="show_txt" id="content_1"></div>
</body>
撰寫 js 腳本實作列印功能,在頁面加載時就呼叫列印函式 typing,并且在動態圖播放到最后一幅時,將其替換成靜態圖:
<script type="text/javascript">
/// 顯示文字功能 ----------------------------------
let divTyping = document.getElementById('content_1'); //通過id獲取div節點
let a = 0;
timer = 0;
str = "我們已經相遇 20 天<br>告白后過了 13 天<br>First Kiss 至今 5 天";
function typing () {
if (a <= str.length) { # 從第一個字開始逐個列印
divTyping.innerHTML = str.slice(0, a++) + '_';
timer = setTimeout(typing, 50); # 設定列印時間間隔
}
else {
divTyping.innerHTML = str; //結束打字,移除 _ 游標
clearTimeout(timer);
}
}
window.onload=function(){
typing();
setTimeout(function(){
thisdiv = document.getElementById("process");
thisdiv.style.backgroundImage = "url('./process_stop.png')"; # 將div背景圖替換
},2000); # 單位是毫秒,根據動態圖的時長來設定
}
</script>
來看一下,真的是真的.真.最終效果圖:
PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取
可以免費領取原始碼、專案實戰視頻、PDF檔案等
本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
作者:凹凸資料
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/43185.html
標籤:Python
上一篇:Python全堆疊課程003
