程序員用python給了女友一個(gè)七夕驚喜!

七夕(各種節(jié)日、紀(jì)念日)又快到啦,程序員(怎么會(huì)不是單身呢)又要想招來哄女友啦?
想必大家都知道各種各樣的代碼式浪漫,比如定制的二維碼,讓女友掃碼后進(jìn)入一個(gè)定制的 h5 頁面,那么這個(gè)頁面里可以放的內(nèi)容是——
回憶,是經(jīng)典的選項(xiàng)。該如何呈現(xiàn)回憶呢?
不難想到可以用 js 來實(shí)現(xiàn)各種動(dòng)畫效果,直接 copy 各種庫組合組合是不錯(cuò),但親力親為還是需要經(jīng)過精心設(shè)計(jì),操作起來有一定的難度。
這里給大家提供一個(gè)簡單的點(diǎn)子,用 python 來制作酷炫的動(dòng)態(tài)條形圖,展示你們?cè)谝黄鸬臍v程吧!
例子如下:

一、動(dòng)態(tài)條形圖
首先,不妨猜想一下這個(gè)是如何實(shí)現(xiàn)的。動(dòng)畫即是一幀一幀靜態(tài)畫面的連續(xù)播放,所以我們只需要將每一天都畫一次圖,再拼成 GIF 即可。
如下為第一天和最后一天的條形圖:


再來看一下用于畫圖的每日數(shù)據(jù),假設(shè)2020年1月1日為起始日期,1月20日為當(dāng)天(即發(fā)布供檢閱的)日期,故要對(duì)這些數(shù)據(jù)畫20次圖(別怕,兄dei)。

進(jìn)入代碼環(huán)節(jié):先按需求讀取數(shù)據(jù)(讀表最愛的 pandas 庫又出現(xiàn)啦)。為了便于處理日期,將 excel 中的日期一列的值轉(zhuǎn)為字符串格式,再利用 datatime 將起始日期設(shè)為時(shí)間戳格式。
import?pandas?as?pd
import?datetime
df?=?pd.read_excel("數(shù)據(jù).xlsx")
df['日期文本']?=?df['日期'].apply(lambda?x:?str(x)[:10])
t?=?datetime.datetime(2020,1,1)?#?起始日期
選擇 matplotlib 庫進(jìn)行繪圖:先設(shè)置畫布,返回模型和畫圖對(duì)象。接著不要忘記設(shè)置字體以避免中文顯示異常。因?yàn)橛?個(gè)項(xiàng)目需要區(qū)分上色,因此再創(chuàng)建一個(gè)顏色列表,可以自行百度喜歡的顏色代碼。
import?matplotlib.pyplot?as?plt
fig,?ax?=?plt.subplots(figsize=(10,6))?#?畫布
plt.rcParams['font.sans-serif']?=?['Microsoft?YaHei']?#?字體設(shè)為微軟雅黑
colors?=?['#ADD8E6',?'#DC143C',?'#FFC0CB']?#?顏色列表
編寫繪圖函數(shù):傳入的參數(shù)是對(duì)于起始日期所經(jīng)過的天數(shù)。通過 t + datetime.timedelta(days=date) 計(jì)算需要繪制的指定天數(shù)的日期,再利用 strftime("%Y-%m-%d") 將其還原為日期文本,然后通過該日期文本取出當(dāng)天的數(shù)據(jù)存入新的 df_ 中。下一步即為通過 barh 方法繪制條形圖,且每次畫新圖前需清空上一次的圖像。
def?draw(date):
????#?數(shù)據(jù)處理?------
????current_date?=?(t?+?datetime.timedelta(days=date)).strftime("%Y-%m-%d")
????df_?=?df[df['日期文本'].eq(current_date)]
????days?=?df_['天數(shù)']
????item?=?df_["項(xiàng)目"]
????#?繪制條形圖?------
????ax.clear()?#?重繪
????#?for?i?in?range(1,len(itme.uni))
????ax.barh(item,?days,?color?=?colors)
如此之后,調(diào)用 draw(19) 來畫出經(jīng)過19天后,也就是第20天的圖像,通過 plt.show() 臨時(shí)查看一下。

和最終效果圖還有一定的差距,多了坐標(biāo)軸標(biāo)簽,少了系列標(biāo)簽、數(shù)據(jù)標(biāo)注和右上角的滾動(dòng)時(shí)間。繼續(xù)完善 draw 函數(shù):
for?y,?(x,name)?in?enumerate(zip(days.values,item.values)):?#?系列標(biāo)注
????????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')?#?滾動(dòng)時(shí)間
ax.get_xaxis().set_visible(False)?#?隱藏坐標(biāo)軸
ax.get_yaxis().set_visible(False)
接下來就是用 for 循環(huán)畫出20張圖并通過 plt.savefig('xxx.png') 一一保存,再使用 imageio 庫或其他圖像工具來合成 gif 啦!
(不不不,慢著慢著)如果真要這樣做就太麻煩了,下面該祭出這次的主角了!
import?matplotlib.animation?as?ani
matplotlib 庫提供了動(dòng)態(tài)繪圖的模塊,可以幫助我們更加輕松的制作 gif。只需傳入模型、繪圖函數(shù)、和一個(gè) int 類型的列表即可,因此最初設(shè)計(jì) draw 函數(shù)時(shí)所需的參數(shù)是天數(shù) date。interval 參數(shù)為繪制每張圖的時(shí)間間隔,用于在 plt.show() 中檢查效果。最終保存 gif 圖像時(shí)可以通過 fps 參數(shù)設(shè)置幀數(shù)。
timeSlot?=?[x?for?x?in?range(0,20)]?#?時(shí)間軸
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("數(shù)據(jù).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']?#?字體設(shè)為微軟雅黑
timeSlot?=?[x?for?x?in?range(0,20)]?#?時(shí)間軸
colors?=?['#ADD8E6',?'#DC143C',?'#FFC0CB']?#?顏色列表
def?draw(date):
????print(date)
????#?數(shù)據(jù)處理?------
????current_date?=?(t?+?datetime.timedelta(days=date)).strftime("%Y-%m-%d")
????df_?=?df[df['日期文本'].eq(current_date)]
????days?=?df_['天數(shù)']
????item?=?df_["項(xiàng)目"]
????#?繪制條形圖?------
????ax.clear()?#?重繪
????ax.barh(item,?days,?color?=?colors)
????for?y,?(x,name)?in?enumerate(zip(days.values,item.values)):?#?系列標(biāo)注
????????????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')?#?滾動(dòng)時(shí)間
????ax.get_xaxis().set_visible(False)?#?隱藏坐標(biāo)軸
????ax.get_yaxis().set_visible(False)
#?draw(19)
#?plt.savefig('test.png')
animator?=?ani.FuncAnimation(fig,?draw,?frames=timeSlot?,interval?=?100)?#?interval時(shí)間間隔
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',?#?糾錯(cuò)級(jí)別
????????picture?=?'img.jpg',?#?底圖路徑
????????colorized?=?True,?#?彩色
????????contrast?=?1.0,?#?對(duì)比度
????????brightness?=?1.0,?#?亮度
????????save_name?=?'save.jpg',?#?保存文件名
????????save_dir?=?'D:/'?#保存目錄
????)
三、編寫靜態(tài)html頁面
如果需要通過二維碼來訪問你的網(wǎng)站,那就需要先將其部署到服務(wù)器,方法也是多種多樣的,比如某企鵝云,個(gè)人用戶有6個(gè)月的免費(fèi)時(shí)常。我們?cè)谶@里要介紹的是 github(其實(shí)是因?yàn)槲夜镜碾娔X不能上外網(wǎng),測試的時(shí)候用不了企鵝云才用的 github,國內(nèi)手機(jī)訪問還是放在國內(nèi)的服務(wù)器比較快,大概是的)
(嗯?就算你問上不了外網(wǎng)卻能上 github 我也…大概是限制的網(wǎng)段沒覆蓋到吧哈哈)
(嗯?我在公司劃水的事情暴露了嗎)。
不過在那之前,先把本地的 html 寫好吧!
通過開頭的最終(不是最終的)效果圖可以發(fā)現(xiàn),gif 是首尾相接循環(huán)播放的,那最后一天的圖像一下子閃過去就看不清楚了,可以修改一下傳入的時(shí)間序列,把最后一幅圖再畫多幾遍,就有停留的效果了。為了更好地展現(xiàn)效果,下面的圖中所用數(shù)據(jù)的時(shí)間周期改為了從6月1日到8月25日(七夕),經(jīng)過了86天,并增加了兩條項(xiàng)目。
timeSlot?=?[x?for?x?in?range(0,86)]+[85]*15

直接放進(jìn) html 頁面里,就單單一張圖好像還缺了點(diǎn)什么,那就跟隨動(dòng)圖的節(jié)奏在下方打印文字吧。首先設(shè)置兩個(gè) div 的樣式,一個(gè)用于展示 gif,一個(gè)用于打印文字:
<head>
<style>
??.process_gif{??/*顯示動(dòng)態(tài)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 腳本實(shí)現(xiàn)打印功能,在頁面加載時(shí)就調(diào)用打印函數(shù) typing,并且在動(dòng)態(tài)圖播放到最后一幅時(shí),將其替換成靜態(tài)圖:
<script?type="text/javascript">
?///?顯示文字功能?----------------------------------
?let?divTyping?=?document.getElementById('content_1');?//通過id獲取div節(jié)點(diǎn)
?let?a?=?0;
?timer?=?0;
?str?=?"我們已經(jīng)相遇?20?天<br>告白后過了?13?天<br>First?Kiss?至今?5?天";
?function?typing?()?{
??if?(a?<=?str.length)?{?#?從第一個(gè)字開始逐個(gè)打印
?????divTyping.innerHTML?=?str.slice(0,?a++)?+?'_';
???timer?=?setTimeout(typing,?50);?#?設(shè)置打印時(shí)間間隔
??}
??else?{
???divTyping.innerHTML?=?str;?//結(jié)束打字,移除?_?光標(biāo)
?????clearTimeout(timer);
??}
?}
?
?window.onload=function(){
???typing();
???setTimeout(function(){
?????????????thisdiv?=?document.getElementById("process");
????thisdiv.style.backgroundImage?=?"url('./process_stop.png')";?#?將div背景圖替換
????????},2000);?#?單位是毫秒,根據(jù)動(dòng)態(tài)圖的時(shí)長來設(shè)置
?}
script>
來看一下,真的是真的.真.最終效果圖:

注意: 動(dòng)圖的時(shí)長和幀數(shù),以及動(dòng)圖在html中與逐行打印文字同步顯示,大家還需根據(jù)實(shí)際內(nèi)容對(duì)代碼進(jìn)行調(diào)整,以達(dá)到最佳效果哦!
好了不想寫了,快速部署的部分大家自己搜索資料吧... ...

四、部署站點(diǎn)到github
言歸正傳,Html 頁面中更多的花樣還有待各位發(fā)揮了,現(xiàn)在到最后環(huán)節(jié)——把頁面 duang 上 github。
先注冊(cè)登錄最大同性交友網(wǎng)站 github(到底有幾個(gè)最大同性交友…)的過程略過,創(chuàng)建一個(gè)新的倉庫,用于存放 html 文件和圖片。

創(chuàng)建后得到一個(gè)倉庫地址。

準(zhǔn)備上傳我們的站點(diǎn)文件。

上傳文件還需要先安裝 git(安裝地址:https://git-scm.com/downloads/),之后在安裝目錄下打開 git-bash.exe。
1、進(jìn)入站點(diǎn)目錄($ 符號(hào)后為輸入的命令):

2、在該目錄生成 git 管理:

3、輸入 add * 添加目錄下所有的文件,也可指定文件名或文件夾,添加文件夾的格式為 add dirname/ :

4、輸入 git status 查看是否將所需文件添加進(jìn)了緩沖區(qū):

5、輸入提交版本的注釋(引號(hào)內(nèi)為注釋內(nèi)容):

6、將本地倉庫管理關(guān)聯(lián)至 github(剛才得到的倉庫地址):

7、上傳文件:

最后一步上傳時(shí)會(huì)相繼彈出 github 賬號(hào)密碼輸入框,輸入后即可等待上傳完成。
完成后回到 github,發(fā)現(xiàn)幾個(gè)文件已經(jīng)躺在倉庫里了,再點(diǎn)擊 Settings:

在 Gitub Pages 一欄中選擇 master branch:

現(xiàn)在,你的站點(diǎn)可以通過這個(gè)鏈接來訪問啦,把它丟進(jìn)二維碼里就大功告成了!可以用手機(jī)掃碼看一下demo。

(如果想知道這種二維碼是如何生成的,請(qǐng)看之前的文章)
事情往往不像看上去那樣簡單,盡管我們已經(jīng)歷盡重重步驟,但依然遺留了兩個(gè)坑:gif 圖片在頁面中加載慢(通過工具壓縮圖片大小來解決),部分瀏覽器不支持 window.onload (優(yōu)化 js 腳本)。本文不再多贅述,大家自己去探索吧(咔咔)!另外,可以加的東西還有詞云、動(dòng)態(tài)字符畫、抽獎(jiǎng)轉(zhuǎn)盤等等,如果各位有什么其他有趣的玩意兒可以加進(jìn)頁面中,還請(qǐng)給筆者提供更多點(diǎn)子!
五、部署站點(diǎn)到企鵝云
最近發(fā)現(xiàn)github有點(diǎn)抽風(fēng),之前部署的站點(diǎn)無法訪問了!于是回家把站點(diǎn)遷到了企鵝云,果然國內(nèi)服務(wù)器響應(yīng)體驗(yàn)更佳,而且操作十分簡便,讓我們來看看怎么做吧。
首先進(jìn)入企鵝云官網(wǎng),在左上角的欄目中找到“對(duì)象儲(chǔ)存”,進(jìn)入頁面后點(diǎn)擊“立即使用”。

然后創(chuàng)建一個(gè)桶子,記得選“公有讀私有寫”,完全私有就不能通過外部訪問啦。


把相關(guān)文件丟到桶子里。

返回桶子列表,在剛才創(chuàng)建的桶子右側(cè)點(diǎn)擊“配置管理”,開啟靜態(tài)網(wǎng)站后就可以通過訪問節(jié)點(diǎn)的鏈接瀏覽站點(diǎn)了,是不是感覺比github page快多了哈哈。

再來掃掃試試吧!~
(如果想知道這種二維碼是如何生成的,請(qǐng)看之前的文章)
以上就是我的分享內(nèi)容,
希望能夠幫助大家七夕哄好女朋友
—?【 THE END 】— 本公眾號(hào)全部博文已整理成一個(gè)目錄,請(qǐng)?jiān)诠娞?hào)里回復(fù)「m」獲取! 3T技術(shù)資源大放送!包括但不限于:Java、C/C++,Linux,Python,大數(shù)據(jù),人工智能等等。在公眾號(hào)內(nèi)回復(fù)「1024」,即可免費(fèi)獲取!!
