前言
2019年年初,新東方年會的一個視頻火爆全網,里面說出了無數職場人士的心聲:
干活的累死累活,到頭來干不過寫PPT的!
也有網友表示:寫好PPT和做好PPT在職場上就是一種能力,一份好的PPT是內容好加視覺美觀,
在平時的科研程序中,我們經常會輸出一些二維的平面圖,二維平面圖反映某個變數在二維場景下的分布情況,
在我們常規的PPT展示中,二維平面圖經常會出現在內容中,但是單單一張二維圖,往往會顯得比較單調,要寫好PPT,首先還是要有好的內容,如何有效并酷炫的展示我們的平面二維結果?先嘗試讓它動起來吧,
準備作業
人生苦短,我用Python,
之前的推送中有提到過Matlab除了不會生孩子,什么都會!把Matlab替換成Python這句話同樣成立,(Matlab與Google Earth一起自定義M_Map岸線)
1.1 用到的資料
水下滑翔機(Underwater Glider)通過浮力調節實作在海水中的升降,并借助固定翼的水動力實作水下滑翔運動,預設軌跡后,其可自動通過攜帶CTD等傳感器測量航線上資料,使用衛星通訊回傳觀測資料、并接受遙控指令,是當前海洋水體自主觀測的新型裝備,也是實作深海大范圍、長時序海洋觀測與探測的有效技術手段,
我們先下載Glider觀測到的一個剖面的溫度資料,同時下載觀測位置處的水深情況為后續資料處理做準備,分別打開以下鏈接后會下載兩個檔案,其中csv檔案是溫度資料,nc檔案是水深資料,
下載鏈接如下:
http://glider.ceotr.ca/data/live/otn200_sci_water_temp_live.csv
https://coastwatch.pfeg.noaa.gov/erddap/griddap/usgsCeSrtm30v1.nc?topo[(45):1:(42)][(-67):1:(-61.5)]
1.2 用到的Python庫
from matplotlib.transforms import Bbox, TransformedBbox, blended_transform_factory from mpl_toolkits.axes_grid1.inset_locator import BboxPatch, BboxConnector, BboxConnectorPatch import matplotlib.pyplot as plt from math import radians, cos, sin, asin, sqrt import pandas as pd import numpy as np import netCDF4 as nc import imageio
動起手來
2.1 資料讀取
nc檔案使用netCDF4庫來讀取檔案中的變數資訊,csv檔案中的資訊使用pandas來讀取,
topo為所在區域的水深情況,lon, lat, date, depth, temp分別為Glider觀測到的站點經度、緯度、觀測時間、深度和溫度,
file2read = r'otn200_sci_water_temp_live.csv' ncfile = r'usgsCeSrtm30v1_6ebb_eec1_d277.nc' data = pd.read_csv(file2read) date = data.iloc[:, 0] lat = data.iloc[:, 1] lon = data.iloc[:, 2] depth = data.iloc[:, 3] temp = data.iloc[:, 4] etopo2 = nc.Dataset(ncfile) latDepth = etopo2.variables['latitude'][:] lonDepth = etopo2.variables['longitude'][:] topo = etopo2.variables['topo'][:]
2.2計算各觀測點之間的距離
因為我們要畫Glider觀測到的斷面的資料情況,對于這個平面圖來說,x方向為斷面上的點距離起點的距離,y方向是水深,平面上展示的為變數的值,先得到斷面上各點之間的距離,
# Compute distance along transectdist = np.zeros((np.size(lon)))for i in range(1, np.size(lon)): dist[i] = dist[i - 1] + haversine(lon[i - 1], lat[i - 1], lon[i], lat[i]) # Compute distance along transect dist = np.zeros((np.size(lon))) for i in range(1, np.size(lon)): dist[i] = dist[i - 1] + haversine(lon[i - 1], lat[i - 1], lon[i], lat[i])
2.3得到斷面上各個點的水深情況
bathy = np.zeros((np.size(lon))) for i in range(np.size(lon)): cost_func = np.abs(lonDepth - lon[i]) xmin = np.where(cost_func == np.min(cost_func))[0] cost_func = np.abs(latDepth - lat[i]) ymin = np.where(cost_func == np.min(cost_func))[0] bathy[i] = -topo[ymin, xmin]
2.4 區域放大影像
區域放大影像并將兩個影像連接起來,主要使用到以下兩個函式:
def zoom_effect(ax1, ax2, xmin, xmax, **kwargs): """ ax1 : the main axes ax1 : the zoomed axes (xmin,xmax) : the limits of the colored area in both plot axes. connect ax1 & ax2. The x-range of (xmin, xmax) in both axes will be marked. The keywords parameters will be used ti create patches. Source: http://matplotlib.org/dev/users/annotations_guide.html#zoom-effect-between-axes """ trans1 = blended_transform_factory(ax1.transData, ax1.transAxes) trans2 = blended_transform_factory(ax2.transData, ax2.transAxes) bbox = Bbox.from_extents(xmin, 0, xmax, 1) mybbox1 = TransformedBbox(bbox, trans1) mybbox2 = TransformedBbox(bbox, trans2) prop_patches = kwargs.copy() prop_patches["ec"] = "r" prop_patches["alpha"] = None prop_patches["facecolor"] = 'none' prop_patches["linewidth"] = 2 c1, c2, bbox_patch1, bbox_patch2, p = \ connect_bbox(mybbox1, mybbox2, loc1a=3, loc2a=2, loc1b=4, loc2b=1, prop_lines=kwargs, prop_patches=prop_patches) ax1.add_patch(bbox_patch1) ax2.add_patch(bbox_patch2) ax2.add_patch(c1) ax2.add_patch(c2) ax2.add_patch(p) return c1, c2, bbox_patch1, bbox_patch2, p def connect_bbox(bbox1, bbox2, loc1a, loc2a, loc1b, loc2b, prop_lines, prop_patches=None): # Fuctions for zoom effect **************************************************** # Source: http://matplotlib.org/dev/users/annotations_guide.html#zoom-effect-between-axes if prop_patches is None: prop_patches = prop_lines.copy() prop_patches["alpha"] = prop_patches.get("alpha", 1) * 0.2 c1 = BboxConnector(bbox1, bbox2, loc1=loc1a, loc2=loc2a, **prop_lines) c1.set_clip_on(False) c2 = BboxConnector(bbox1, bbox2, loc1=loc1b, loc2=loc2b, **prop_lines) c2.set_clip_on(False) bbox_patch1 = BboxPatch(bbox1, **prop_patches) bbox_patch2 = BboxPatch(bbox2, **prop_patches) p = BboxConnectorPatch(bbox1, bbox2, # loc1a=3, loc2a=2, loc1b=4, loc2b=1, loc1a=loc1a, loc2a=loc2a, loc1b=loc1b, loc2b=loc2b, **prop_patches) p.set_clip_on(False) return c1, c2, bbox_patch1, bbox_patch2, p
2.5 生成多張圖片
要生成動圖,首先要準備多張圖片來成為動圖每一幀的素材,在下面這段代碼中,nframes表示生成多少幅圖,這個相當于將平面圖在x方向分割成nframes個部分,在平面圖的下方新建一個圖層,然后將分割出來的部分再展示出來,實作區域放大效果,
# Make plots nframes = 20 overlap = 0.95 window = np.floor(max(dist) - min(dist)) / (nframes - (nframes * overlap) + overlap) xmin = 0 xmax = xmin + window cmp = plt.cm.get_cmap('jet', 16) fig1 = plt.figure() for i in range(0, nframes): ax1 = plt.subplot(211) plt.fill_between(dist, bathy, 1000, color='k') plt.scatter(dist, np.asarray(depth), s=15, c=temp, cmap = cmp, marker='o', edgecolor='none') plt.ylim((-0.5, max(depth) + 5)) ax1.set_ylim(ax1.get_ylim()[::-1]) cbar = plt.colorbar(orientation='vertical', extend='both') cbar.ax.set_ylabel('Temperature ($^\circ$C)') plt.title('OTN Glider transect') plt.ylabel('Depth (m)') ax1.set_xlim(min(dist), max(dist)) ax2 = plt.subplot(212) plt.fill_between(dist, bathy, 1000, color='k') plt.scatter(dist, depth, s=15, c=temp, cmap= cmp, marker='o', edgecolor='none') plt.ylim((-0.5, max(depth) + 5)) ax2.set_ylim(ax2.get_ylim()[::-1]) plt.ylabel('Depth (m)') plt.xlabel('Distance along transect (km)') ax2.set_xlim(xmin, xmax) zoom_effect(ax1, ax2, xmin, xmax) file2write = 'glider_' + '%02d'%i + '.png' plt.savefig(file2write, bbox_inches='tight') plt.close() xmin = xmax - np.floor(window * overlap) xmax = xmin + window
2.6 生成gif檔案
這里使用到一個imageio的庫,首先讀取上文中生成的靜態圖到串列,作為GIF的每一幀;接著設定輸入(靜態圖)、輸出(動態圖)和一些必要引數,我們這里設定每一幀間隔時間為0.3秒,默認是1秒,可以通過調整dutation來設定逐幀之間的間隔時間,之后呼叫imageio.mimsave函式去保存結果,
這段代碼中我們用到了串列推導式,參見另外一篇推送中的介紹,
imagelist = ['glider_'+'%02d'%i +'.png' for i in range(0,20)] frames = [imageio.imread(_) for _ in imagelist] outname = 'gliders.gif' imageio.mimsave(outname, frames, 'GIF', duration=0.3)
小結
一圖勝千言,就用本篇生成的動圖來結束這篇推送吧,
PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取
可以免費領取原始碼、專案實戰視頻、PDF檔案等
本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
以上文章來源于海洋紀 ,作者劉夏橙
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/40969.html
標籤:Python
上一篇:并發編程——行程應用(multiprocessing模塊介紹,Process類介紹),Process物件的join方法
