在模仿中精進數據可視化05:疫情期間市值增長top25公司

2020-12-23 小老鼠Python

本文完整代碼及數據已上傳至我的Github倉庫https://github.com/CNFeffery/FefferyViz

1 簡介

新冠疫情對很多實體經濟帶來衝擊的同時,也給很多公司帶來了新的增長點。前段時間我看到圖1所示的數據可視化作品,針對2020年1月1日到6月16日之間,世界範圍內市值增大最多的25家公司進行可視化:

圖1

這樣一張典型的商業圖表,看起來形式巧妙,且表現出很多數據信息。而今天的文章,我就將帶大家學習如何利用

matplotlib

來條理清楚地製作出這種類型的可視化作品。

2 模仿過程

首先我們還是像過往的文章中一樣分析一下原作品的元素構成:

「立體感的營造」其實原作品咋一看起來的立體感,只是玩了個花招,我們本質上只需要創建出最左列豎直方向上等分25份的填充區域,再向右偏移適合的距離後,縮小豎直方向上的總體範圍再25等分,最後將這兩部分等分的填充區域連接起來,最後再為中間的連接區域蒙上一層等大小的帶透明度的暗色蒙版即可~

「logo與國旗圖片的插入」原作品中眾多圖片,只要仔細觀察就可以發現是手動PS上去的,存在著一些微小的瑕疵,而我們既然要用

matplotlib

來製作這張圖,當然直接寫循環控制圖片的插入即可。

matplotlib

中向畫板插入其他圖片有很多方法,我們為了控制好眾多logo之間的協調,可以使用

matplotlib

中的

inset_axes()

來插入指定位置和尺寸的子圖。

「數值標註的控制」原作品中不同公司市值增長的不同體現在不同長度柱體以及不同大小文字標註的映射之上的,我們可以配合簡單的歸一化變換,來約束字體和柱體長度的映射。

搞明白原作品中主要元素的實現方式之後,我們首先來讀入原始數據(「公眾號後臺回復top25獲取本文全部附件」):

import matplotlib.pyplot as pltimport pandas as pd# 設置默認字體plt.rcParams['font.sans-serif'] = ['Times New Roman']raw = pd.read_excel('data.xlsx')raw.head()

圖2

接著為了方便處理公司類型向指定配色的映射,我們先來創建一個映射字典:

type2color = {'Technology': '#e2a080', 'E-Commerce': '#ebb66a', 'Automotive': '#c198ba', 'Finance': '#aab5d8', 'Tele-communications': '#bdd7e4', 'Media': '#efcfde', 'Software': '#d5c1c4', 'Pharmaceutical': '#f9e4ad', 'Alcohol': '#c3d3ac', 'Retail': '#88bb70'}

而為了創建出原作品中最重要的不同條帶,我們可以配合

matplotlib

中的

fill_between()

而為了處理好左側與右側的豎直方向25等分區域,我們可以在對原數據每一行循環的過程中,自定義下列函數來計算區域範圍:

def create_fill_area(row, top_y=0.8, bottom_y=0.01):# 初始化包圍填充區域的上下線條y坐標 line1, line2 = [1 - 0.04*row, 1 - 0.04*row], [1- 0.04*(row+1), 1- 0.04*(row+1)] # 追加陰影段y坐標 line1.append(0.01 + (25 - row) * (0.8 - 0.01) / 25) line2.append(0.01 + (25 - row - 1) * (0.8 - 0.01) / 25) # 追加最後一段平行段y坐標 line1.append(0.01 + (25 - row) * (0.8 - 0.01) / 25) line2.append(0.01 + (25 - row - 1) * (0.8 - 0.01) / 25) return line1, line2

做好這些準備工作之後,剩餘的繪圖過程就很簡單了,最終得到的模仿作品如下:

圖3

完整代碼如下,雖然看起來略多,其實大部分都是重複的邏輯傳入不同的參數而已,還是比較簡單的:

fig, ax = plt.subplots(figsize=(4.8, 6))ax.set_xlim(0, 1.01)ax.set_ylim(0, 1)for row in range(raw.shape[0]):# 定義區域填充對應的x坐標 x = [0, 0.15, 0.215, 0.6+raw.at[row, 'Grown'] / 1000] # 生成區域填充對應的y坐標 line1, line2 = create_fill_area(row) # 對指定區域進行填充 ax.fill_between(x, line1, line2, color=type2color[raw.at[row, 'Type']], edgecolor='none') # 從logo文件夾下讀取對應logo圖片 try: logo = plt.imread(f'logo/{raw.at[row, "Company"]}.png') except FileNotFoundError: logo = plt.imread(f'logo/{raw.at[row, "Company"]}.jpg') # 插入公司logo ax_logo = ax.inset_axes((0.05, 1 - 0.04*(row+1)+0.005, 0.08, 0.025)) ax_logo.imshow(logo) ax_logo.axis('off') ax_logo.set_facecolor(type2color[raw.at[row, 'Type']]) # 處理單個及多個國家情況下的國旗繪製 for idx, country in enumerate(raw.at[row, 'Country'].split('&')[::-1]): # 讀取對應國旗圖片 flag = plt.imread(f'flag/{country}.png') # 插入國旗子圖 ax_flag = ax.inset_axes((0.545-idx*0.06, 0.013+(25 - row - 1)*((0.8 - 0.01) / 25), 0.1, 0.025)) ax_flag.imshow(flag) ax_flag.axis('off') ax_flag.set_facecolor(type2color[raw.at[row, 'Type']]) # 繪製排名 ax.text(0.025, (1 - 0.04*row + 1 - 0.04*(row+1)) / 2, str(row+1), ha='center', va='center', fontsize=5, color='black') # 繪製公司名稱 ax.text(0.215+0.01, 0.5 * (0.01 + (25 - row - 1) * (0.8 - 0.01) / 25 + 0.01 + (25 - row) * (0.8 - 0.01) / 25), raw.at[row, 'Company'], ha='left', va='center', fontsize=6, color='#494948', weight='bold') # 處理第一名文字在填充區域內部,其餘文字在填充區域外的情況 if raw.at[row, 'Company'] == 'Amazon': ax.text(1, 0.5 * (0.01 + (25 - row) * (0.8 - 0.01) / 25 + 0.01 + (25 - row - 1) * (0.8 - 0.01) / 25)-0.0025, '$'+str(raw.at[row, 'Grown'])+'B', color='white', fontsize=10, ha='right', va='center', weight='bold') else: # 配合歸一化對字體進行大小映射 ax.text(0.6+raw.at[row, 'Grown'] / 1000 + 0.01, 0.5 * (0.01 + (25 - row) * (0.8 - 0.01) / 25 + 0.01 + (25 - row - 1) * (0.8 - 0.01) / 25)-0.0025, '$'+str(raw.at[row, 'Grown'])+'B', color=type2color[raw.at[row, 'Type']], fontsize=5+((raw.at[row, 'Grown'] - raw['Grown'].min()) / (raw['Grown'].max() - raw['Grown'].min())) * 5, ha='left', va='center', weight='bold')# 對指定區域進行帶透明度的黑色蒙版,以達到陰影效果ax.fill_between([0.15, 0.215], [0, 0.01], [1, 0.8], color='black', alpha=0.2, # 設置透明度 edgecolor='none')# 補充其餘文字標註ax.text(0.215+0.01, 0.805, 'Company', color='#565555', fontsize=5, ha='left')ax.text(0.6, 0.805, 'Country', color='#565555', fontsize=5, ha='center')# 補充上方數值刻度ax.text(0.6, 0.825, '0', color='#a9a8a8', fontsize=4, ha='center')for i in range(1, 5): ax.text(0.6+0.1*i, 0.825, f'${i}00B', color='#a9a8a8', fontsize=4, ha='center') ax.vlines(0.6+0.1*i, 0.01, 0.82, color='#dcdcdb', linewidth=0.2)ax.set_xticks([])ax.set_yticks([])ax.spines['left'].set_color('none')ax.spines['right'].set_color('none')ax.spines['top'].set_color('none')ax.spines['bottom'].set_color('none')# 補充下排圖例ax_bar1 = ax.inset_axes((0.215, 0.88, 0.57, 0.02), transform=ax.transAxes)ax_bar1.set_xlim(-0.45, 4.45)ax_bar1.bar(range(5), height=1, width=0.9, color=['#efcfde', '#d5c1c4', '#f9e4ad', '#c3d3ac', '#88bb70'])ax_bar1.set_xticks(range(5))ax_bar1.set_xticklabels(['Media', 'Software', 'Pharmaceutical', 'Alcohol', 'Retail'], fontsize=5, color='#4f4e4e', weight='bold')ax_bar1.set_yticks([])ax_bar1.spines['left'].set_color('none')ax_bar1.spines['right'].set_color('none')ax_bar1.spines['top'].set_color('none')ax_bar1.spines['bottom'].set_color('none')ax_bar1.tick_params(color='none', pad=-2)ax_bar1.set_facecolor('#f8f8f8')# 補充上排圖例ax_bar2 = ax.inset_axes((0.215, 0.98, 0.57, 0.02), transform=ax.transAxes)ax_bar2.set_xlim(-0.45, 4.45)ax_bar2.bar(range(5), height=1, width=0.9, color=['#e2a080', '#ebb66a', '#c198ba', '#aab5d8', '#bdd7e4'])ax_bar2.set_xticks(range(5))ax_bar2.set_xticklabels(['Technology', 'E-Commerce', 'Automotive', 'Finance', 'Tele-\ncommunications'], fontsize=5, color='#4f4e4e', weight='bold')ax_bar2.set_yticks([])ax_bar2.spines['left'].set_color('none')ax_bar2.spines['right'].set_color('none')ax_bar2.spines['top'].set_color('none')ax_bar2.spines['bottom'].set_color('none')ax_bar2.tick_params(color='none', pad=-2)ax_bar2.set_facecolor('#f8f8f8')ax.set_facecolor('#f8f8f8')fig.set_facecolor('#f8f8f8')fig.savefig('圖3.png', dpi=800, bbox_inches='tight')

你可以自由嘗試不同的配色方案,或者換成你的數據,快速製作出同樣別致的可視化作品~

以上就是本文的全部內容,歡迎在評論區與我進行討論~

相關焦點

  • 可視化腦洞十五個數據可視化的奇妙例子
    、財新數據可視化實驗室創始人黃志敏老師,從本期開始擔任可視化專欄特約欄目主編。那必定意味著數據可視化比得上千言萬語,對不對?無論如何,是時候讓我們收羅一些最具視覺衝擊力的複雜數據集了。以下是我最喜歡的15個例子。
  • 近4000億元市值順豐的奔跑動能
    數據顯示,截止到11月30日,A股上市公司市值排名的TOP30,與2019年末市值相比,除了新上市的兩家公司外,只有6家公司市值縮水,其他公司市值均不同程度上升,更有4家公司實現了市值翻倍,分別是寧德時代、比亞迪、中國中免和順豐控股,意料之外又在意料之中。
  • 大公司都是怎麼做數據可視化規範的
    上周,表哥分享了一篇關於,洋洋灑灑四千多字把可視化規範背後的原則研究了個遍。但在實際工作中,可視化常常是在多人協作中完成的,我們該如何制定一份可視化標準來確保跨人員、跨平臺設計呢?我們常聽到視覺識別系統(VIS),可視化有沒有專門的設計系統呢?
  • 新冠疫情地圖可視化 - 零新增確診地圖
    19世紀約翰·斯諾醫生製作的霍亂地圖則開啟了利用地圖這一形式進行多元數據融合推斷,進行決策的先河。在針對新冠疫情的工作中,北京大學可視化與可視分析實驗室研發製作了一系列交互地圖。在此我們討論通過數據繪製各類主題地圖,幫助更好的理解疫情發展變化。今天我們介紹其中的零新增地圖。1.
  • 八合裡:疫情期間公司運行狀況良好,外賣業務持續增長
    2月16日,八合裡相關負責人回應證券時報表示,目前公司運行狀況良好,在當下沒有貸款需求。針對新型冠狀肺炎疫情期間餐飲行業普遍面臨的停業難題,該負責人表示,「八合裡不希望給國家添麻煩,能自己解決的就自己解決,哪怕是賣房子。目前企業的運行狀態還算是良好,處於復產階段。如果社會恢復到正常情況下,我們也能逐步恢復到往常的經營狀態。
  • 大數據:為什麼企業管理者需要更好的進行「數據分析可視化」?
    不同於文字信息傳播的種種限制,圖像可以在不同語言、不同層面的人群中傳播,並且人的大腦可以快速獲取和處理圖像信息。研究表明,圖像信息在視覺和人腦一起作用下,大約13毫秒內便可以處理完成。比如,當你在查看數據視圖時,可以立即知道哪個節點出現了異常;如果使用文字編寫數據分析而不是可視化的圖表時,則需要從頭將數據整理歸納並運用一定的計算才能得出對「異常點」的推論。
  • 周獲4700 Star 全球疫情數據可視化系統,超輕量級中文 OCR...
    作者 | HelloGitHub-小魚乾來源 | HelloGitHub摘要:連著兩周成績平平的 GitHub Trending 榜,終於和三月的天氣一樣進入全面變暖的模式,無論是本周剛開源搭乘 OCR 熱點並獲得 1,500+ star 的 chineseocr_lite,還是借著國外疫情大爆發這股「東風」一周獲得近 5,000+ star 的可視化項目
  • 可視化就這麼玩
    喜的是他小A,一個很早就認識的學員,一直保持著亦師亦友的關係。最近小A興奮得來找我說,他們單位老大直接找他為一份年度報告配圖表,他已經激動得幾天沒睡好覺了,現在人送雅號「圖表小王子」。真為小A高興。 喜的還有他小B,小B的「突然造訪」真讓人意外。
  • 快到年底了,聊聊數據可視化
    年底快到了,又到了「打工人」做匯報的時候,也許你負責市場部,可能你是銷售負責人,或者僅僅匯報個人在幾個項目中的表現,無論怎樣,你都不可能把原始數據展示給大家,你或多或少會採用某種「可視化」的方法,直觀傳達你想表達的重點信息,那麼問題來了,可視化包含什麼,怎麼做可視化,有哪些方法可以做好可視化?
  • 火爆抖音、B站的數據可視化動態視頻都是如何製作的?
    最近世界疫情越來越嚴重,小編在關注疫情的發展情況過程中,再一次拜倒在數據可視化的石榴裙下,話不多說,請看以下動畫。類似的視頻最近在抖音、B站上非常火爆!短短兩分鐘數據可視化的動態視頻可以讓我們非常清楚的了解疫情隨時間的變化趨勢,比如各個國家感染人數情況,還可以對比每個國家疫情的嚴重程度等等.......你是不是也在感嘆數據可視化的神奇力量。
  • 市值逼近500億美元,電商和魔鏡助lululemon逆勢增長
    在室外運動紛紛叫停、公共健身場所關閉的情況下,疫情期間,居家健身成為了潮流。沒有裁員、沒有取消工廠訂單、也沒有大幅降價處理滯銷產品,加拿大運動品牌lululemon也憑藉著瑜伽服飾業務,迎來了逆勢增長。今年以來,該公司的股價上漲幅度近59%。
  • pandas數據可視化原來也這麼厲害
    作者:小伍哥 來源:AI入門學習(公眾號)在python中,常見的數據可視化庫有3個:matplotlib:最常用的庫,可以算作可視化的必備技能庫,比較底層,api多,學起來不太容易。seaborn:是建構於matplotlib基礎上,能滿足絕大多數可視化需求,更特殊的需求還是需要學習matplotlib。pyecharts:上面的兩個庫都是靜態的可視化庫,而pyecharts有很好的web兼容性,可以做到可視化的動態效果。並且種類也比較豐富。
  • 貴州茅臺品牌價值持續增長 食品飲料品牌中唯一入局「中國上市公司...
    期間,中國在世界抗擊病毒戰場上的表現有目共睹,一眾上市公司也展現了大企業的責任與擔當。在這一背景下,今年的中國上市公司品牌價值榜似乎有了更多的意義與內涵。今年是「2020中國上市公司品牌價值榜」連續第四年重磅揭曉。四年間,這份榜單始終以評選客觀、標準專業受到資本市場的廣泛認可,並成為業內評估企業品牌價值重要的參考樣板。
  • 威海市公安局運用大數據實現疫情防控
    在來勢洶洶的疫情之下,作為公共安全、交通、人口管理等與疫情防控息息相關領域的責任部門,威海市公安局全員上崗,在抗擊新冠疫情的戰鬥中一直處於一線。他們堅持「大數據+智慧警務」,整合多方數據資源,聯合高校和信息化高科技公司,發揮技術手段優勢,研發疫情防控大數據系統,搭建大數據防疫模型,實現數據有效上圖,可視化呈現,對高風險人員精準預警研判,精確排查管控,為奪取疫情防控和復工復產雙勝利提供了有力的「智力」支撐。
  • 如何使用JMP繪製地圖實現數據可視化
    隨著時代的變遷和數據量的爆炸式增長,地圖的概念也不斷地拓展和變化。本文引用地址:http://www.eepw.com.cn/article/185666.htm越來越多的分析人士把包含目標數據的地圖看作是數據可視化中的重要組成部分,喜歡將具有地域特徵的數據或者數據分析結果形象化地表現在地圖上,使人們可以更容易地理解數據規律和趨勢。
  • 數據新聞精選:在疫情中發酵的種族議題
    在六月,除了全世界範圍內對種族歧視的抗議浪潮,還有更多的議題進入數據記者的視野:停工減薪的失業潮中,階級固化與貧富差距將會使社會進一步分裂嗎?居家辦公的過程中,女性是否又被迫回到了負擔所有家務的傳統角色中?人類社會停擺導致的各種排放物減少,對於自然環境是否反而是件好事?在這些精彩的討論中,全球深度報導網為你這些值得一看的數據新聞。
  • 萬國數據掌舵人黃偉今天再次敲鐘:做出1200億市值
    之後萬國數據的股價表現,證明了黃偉的選擇是正確的。上市至今近4年裡,萬國數據股價上漲超7倍,以美東時間10月30日收盤價計,公司總市值達137.7億美元,已成為全球市值第三的IDC企業。如今,黃偉再次站上敲鐘舞臺。美股上市四年後,萬國數據今天在港交所成功掛牌上市,發行價80.88港元,開盤後市值達到1200億港元。
  • 超酷炫.NET數據可視化組件LightningChart
    LightningChart Ultimate SDK是Arction Ltd公司開發的.NET和Windows 2D和3D測量、管理和研發數據可視化SDK。它是一個能全面實現GPU加速(Direct3D)和性能優化的數據控制項,大規模數據都可以通過它以二維XY圖表、三維XYZ圖表、極坐標圖、餅圖和環面圖等圖表展現出來。從v5.0開始,也包括WPF圖表。LightningChart Ultimate for WPF使用帶有本公司自主開發的圖形程序的低級DirectX。其他WPF圖表建立了慢系統/窗口/媒體圖形程序,主要區別在於渲染性能。
  • 創業板市值第二大公司易主了!
    公司主要營收之一的食用油板塊在國內市佔率穩居第一,市場份額達到34%;第二名是中糧;第三名是魯花,後兩者合計份額還不到23%。2020年前三季度,公司實現營收1399.93億元,同比增長11.71%,其中第三季度營收530.20億元,比上年同期增長13.70%;歸母淨利潤50.9億元,同比增長45.88%。
  • 打通數據價值最後一公裡:一文讓你全面了解數據可視化
    圖形和地圖的元素,在數據可視化的具體應用中,可以單一使用(參考上圖進行選擇),也可以綜合使用,這就是數據可視化的呈現方式,或者說可視化元素如何滿足不同最終用戶的需求。