程序猿如何畫出精美的桑基圖

畫各種軟件工程圖對於程序猿來說是家常便飯。比較簡單的結構圖、流程圖、數據流圖、類圖、柱狀圖之類的用Visio、XMind、PowerPoint、Excel也就算了,再複雜一點的,如決策樹之類的圖,用"億圖"之類的軟件也可以將就。更多時候畫出既能完美表達思路又線條優美的圖卻是難上加難。


最近看了一篇ceph大神的博客,用桑基圖描述crush(一種分佈式文件系統的副本分佈策略),既形象又優美,那麼怎麼才能畫出這種圖呢?
在這裏插入圖片描述
原文地址: http://www.zphj1987.com/2019/03/08/ceph-pg-crush-fast-check/#more
答案:用代碼畫,雖然有時候會費點勁兒,但有更大的發揮空間。

安裝配置

環境介紹

主要軟件:

  • anaconda2019.03
  • jupyter notebook
  • pyecharts
  • Linux/Mac/Windows

主要思路:用python的pyecharts畫圖

搭建python的運行環境,本文選擇使用anaconda。

anaconda官網:https://www.anaconda.com/distribution/

對於Mac和Windows一鍵安裝即可,在安裝時注意把註冊環境變量的選項勾上。打開命令終端後的使用過程各平臺都相同。

不過作爲一款服務軟件,自然首選安裝在服務器上,因此,本文以Centos7爲例,介紹安裝和使用過程。

安裝anaconda

# 安裝依賴包
yum install -y wget tar zip unzip curl bzip2
# 下載安裝包
wget https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh
# 安裝
bash Anaconda3-2019.03-Linux-x86_64.sh

安裝過程中按"空格"跳過聲明信息,按提示輸入"yes"和"安裝目錄"後,繼續安裝步驟,安裝過程即可順利完成。安裝完成後,開啓一個新的shell終端窗口進行後續操作。

配置操作系統

注:爲了方便演示才進行如此配置,生產環境請勿執行以下命令。

# 關閉防火牆
systemctl stop firewalld.service
systemctl disable firewalld.service
systemctl stop iptables
setenforcing 0

安裝jupyter notebook

conda install jupyter

配置jupyter

# 生成配置文件
jupyter notebook --generate-config
# 設置登錄密碼
jupyter notebook password

設置密碼時連續輸入兩次密碼即可。

安裝圖形庫

pip install pyecharts

畫圖

啓動jupyter notebook

jupyter notebook --allow-root --ip=0.0.0.0 --port=8888

用代碼畫圖

訪問地址:“http://SERVER_IP:8888”,
密碼:上面步驟中設置的密碼
詳細步驟如下圖:
在這裏插入圖片描述
代碼:

nodes = [
	{'name': 'category1'},
	{'name': 'category2'}, 
	{'name': 'category3'},
    {'name': 'category4'}, 
    {'name': 'category5'}, 
    {'name': 'category6'},
]
#nodes需要把桑基圖中出現的名稱全部設置進去,並且要保證links中的名稱與name相同
links = [
    {'source': 'category1', 'target': 'category2', 'value': 10},
    {'source': 'category2', 'target': 'category3', 'value': 15},
    {'source': 'category3', 'target': 'category4', 'value': 20},
    {'source': 'category5', 'target': 'category6', 'value': 25}
]
#links代表節點關係,source表示起點,target表示終點,需要將節點關係全部輸入進去,value表示節點長度
from pyecharts import options as opts
from pyecharts.charts import Page, Sankey

sankey = Sankey()		#可以設置大小和圖標名稱
sankey.add(
    'sankey',				#名稱
    nodes,					#輸入節點,如果導入json數據,nodes=json['nodes]
    links,					#輸入關係,nodes=json['links']
    linestyle_opt=opts.LineStyleOpts(opacity=0.2, curve=0.5, color="source", width=1600),
    label_opts=opts.LabelOpts(position="right", is_show=True, color='red'),
    node_gap=20
)
sankey.render()

結語

pyecharts不僅僅可以畫桑基圖,python也不止有pyecharts一種圖形庫,因此用python畫圖有很大的發揮空間。尤其是畫數學模型相關的圖,更是手到擒來。如下:
在這裏插入圖片描述
給大家留一個練習題,下面這張分型圖近些年比較火,那麼它是如何畫的?
在這裏插入圖片描述
代碼:

import numpy as np
from PIL import Image
from numba import jit
MAXITERS = 200
RADIUS = 100

@jit
def color(z, i):
	v = np.log2(i+1-np.log2(np.log2(abs(z))))/5
	if v < 1.0:
		return v**4, v**2.5, v
	else:
		v = max(0, 2-v)
		return v, v**1.5, v**3

@jit
def iterate(c):
	z = 0j
	for i in range(MAXITERS):
		if z.real*z.real +z.imag*z.imag > RADIUS:
			return color(z, i)
		z = z*z + c
	return 0, 0, 0

def main(xmin, xmax, ymin, ymax, width, height):
	x = np.linspace(xmin, xmax, width)
	y = np.linspace(ymax, ymin, height)
	z = x[None, :] +y[:, None]*1j
	red, green, blue = np.asarray(np.frompyfunc(iterate, 1, 3)(z)).astype(np.float)
	img = np.dstack((red, green, blue))
	Image.fromarray(np.uint8(img*255)).save('mandelbrot.png')
	
main(-2.1, 0.8, -1.16, 1.16, 1200, 960)

關注麻辣軟硬件,獲取更多有料的軟硬件知識

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章