公衆號:尤而小屋
作者:Peter
編輯:Peter
大家好,我是Peter~
之前更新了很多關於Plotly繪圖的文章。今天帶來的文章是基於官網和實際案例來講解如何繪製不同需求下的熱力圖。
Plotly中繪製熱力圖有3種方式:heatmap、imshow和figure_factory(Plotly的圖形工廠函數)
官網學習地址:
- https://plotly.com/python/heatmaps/
- https://plotly.com/python/imshow/
- https://plotly.com/python/annotated-heatmap/
目錄
本文的整體目錄:
Plotly連載文章
幾篇Plotly更新的文章,請參考:
導入庫
import pandas as pd
import numpy as np
import plotly_express as px
import plotly.graph_objects as go
import plotly.figure_factory as ff # 圖形工廠
from plotly.subplots import make_subplots # 繪製子圖
基於px展示imshow
Plotly中的imshow主要是用來展示圖像數據,當然也可以用來顯示熱力圖:
展示RGB圖形數據
# 數據部分
rgb = np.array([[[105, 0, 0], [0, 255, 0], [0, 0, 55]],
[[0, 250, 0], [0, 0, 205], [255, 0, 0]]],
dtype=np.uint8)
# 調用px
fig = px.imshow(rgb)
fig.show()
基於嵌套列表
fig = px.imshow([[1, 20, 30],
[20, 1, 60]])
fig.show()
基於二維數組的數據
1、顯示顏色棒及顏色
data = np.arange(20).reshape(4,5) # 如何使用Numpy生成數據
fig = px.imshow(data)
fig.show()
2、不顯示顏色棒+灰色
data = np.arange(20).reshape(4,5)
fig = px.imshow(data,binary_string=True) # 參數設置
fig.show()
3、顯示灰色+顏色棒
data = np.arange(20).reshape(4,5)
fig = px.imshow(data,color_continuous_scale="gray") # 參數設置
fig.show()
基於圖形文件中的數據
1、基礎圖形
# 從skimage中導入數據
from skimage import data
# 導入指定圖像數據
img = data.astronaut()
fig = px.imshow(img,
binary_format="jpeg",
binary_compression_level=0)
fig.show()
2、不顯示座標軸刻度
# 從skimage中導入數據
from skimage import data
# 導入指定圖像數據
img = data.astronaut()
fig = px.imshow(img,
binary_format="jpeg",
binary_compression_level=0)
# 不顯示顏色範圍和軸刻度
fig.update_layout(coloraxis_showscale=False)
fig.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False)
fig.show()
自定義軸刻度值
import plotly.express as px
data=[[1, 25, 30, 50, 100],
[20, 10, 60, 80, 30],
[13, 60, 31, 5, 20]]
fig = px.imshow(
data, # 傳入數據
# 軸標籤設置
labels=dict(x="Week", y="Time of Day", color="Productivity"),
# 軸刻度設置
x=['星期一', '星期二', '星期三', '星期四', '星期五'],
y=['早', '中', '晚']
)
# 軸位置調整
fig.update_xaxes(side="top")
fig.show()
基於go展示imshow
graph_objects方法支持兩種方法來繪製圖像繪製:
- go.Image:僅支持多通道的圖像數據
- go.Heatmap:支持單通道的圖像數據
基於go.Image方法
import plotly.graph_objects as go
# 2*3*3的列表
rgb = [[[200, 0, 0], [0, 200, 0], [0, 0, 255]],
[[0, 255, 0], [0, 0, 205], [255, 0, 0]]]
fig = go.Figure(go.Image(z=rgb))
fig.show()
基於go.heatMap方法
import plotly.graph_objects as go
fig = go.Figure(data=go.Heatmap(
z=[[10, 20, 30],
[20, 1, 60],
[30, 60, 10]]))
fig.update_layout(width=800,height=500)
fig.show()
缺失值處理
import plotly.graph_objects as go
fig = go.Figure(data=go.Heatmap(
z=[[1, None, 30, 50, 1], [20, 1, 60, np.nan, 30], [30, 60, 1, -10, 20]],
x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
y=['Morning', 'Afternoon', 'Evening'],
hoverongaps = False)) # 缺失值處理參數
fig.show()
基於圖形工廠 figure_factory
figure_factory圖形工廠一個重要的作用就是繪製帶有標註的熱力圖。我們可以看到上面的各種圖形都是沒有標註的
基礎圖形
基於圖形工長如何繪製基本待標註的基本圖形:
import plotly.figure_factory as ff
z = [[1.1, .3, .5, .7, .9],
[1, .8, .6, .4, .2],
[.2, 0, .5, .7, .9],
[.9, .8, .4, .2, 0]]
fig = ff.create_annotated_heatmap(z)
fig.show()
自定義顏色
import plotly.figure_factory as ff
z = [[1.1, .3, .5, .7, .9],
[1, .8, .6, .4, .2],
[.2, 0, .5, .7, .9],
[.9, .8, .4, .2, 0]]
# 添加參數:colorscale
fig = ff.create_annotated_heatmap(z,colorscale='Viridis')
fig.show()
如何設置不同的顏色:
import plotly.figure_factory as ff
z = [[.1, .3, .5, .7],
[1.0, .8, .6, .4],
[.6, .4, .2, 0.0],
[.9, .7, .5, .3]]
# 這種寫法通過嵌套列表來指定顏色的漸變,更加靈活
colorscale = [[0.0, 'green'],[0.5, 'blue'],[1, 'yellow']]
# 指定字體的顏色
font_colors = ['white', 'red']
# 傳入字體和顏色參數
fig = ff.create_annotated_heatmap(z, colorscale=colorscale, font_colors=font_colors)
fig.show()
自定義XY軸
import plotly.figure_factory as ff
# 顯示的數據
z = [[101,131,95],
[112,74,146]]
# 兩個軸,可以任意指定
x = ["語文","數學","英語"]
y = ["小明","小紅"]
# 待註釋的數據,一般和z相同
z_text = [[101,131,95],
[112,74,146]]
fig = ff.create_annotated_heatmap(
z,
x=x,
y=y,
annotation_text=z_text, # 標註文本內容
colorscale='Viridis')
fig.show()
設置字體大小
有時候我們更改標準文本中字體的大小:
import plotly.figure_factory as ff
# 顯示的數據
z = [[101,131,95],
[112,74,146]]
# 兩個軸,可以任意指定
x = ["語文","數學","英語"]
y = ["小明","小紅"]
# 待註釋的數據,一般和z相同
z_text = [[101,131,95],
[112,74,146]]
fig = ff.create_annotated_heatmap(
z,
x=x,
y=y,
annotation_text=z_text, # 標註文本內容
colorscale='Viridis')
# 字體大小設置
for i in range(len(fig.layout.annotations)):
fig.layout.annotations[i].font.size=20
fig.show()
實戰1:相關係數熱力圖
使用股票數據
採用的plotly_express內置的股票數據;通過相關係數函數corr函數求解出兩兩公司之間的相關係數
stock = px.data.stocks()
stock.head()
Plotly中內置的一份關於股票的數據:
相關係數
生成相關係數矩陣,同時保留兩位小數:
座標軸和繪圖數據
生成座標軸和待繪圖的數據:
繪圖
import plotly.figure_factory as ff
# 顯示的數據
z = data1
# 兩個軸,可以任意指定
x = index
y = columns
# 顯示的文本內容
z_text = data1
fig = ff.create_annotated_heatmap(
z,
x=x,
y=y,
annotation_text=z_text, # 標註文本內容
colorscale='Viridis',
showscale=True
)
# 字體大小設置
for i in range(len(fig.layout.annotations)):
fig.layout.annotations[i].font.size=12
fig.show()
案例2:繪製任意座標軸熱力圖
這個案例是自己曾經遇到的一個問題的解決過程,就是當我們的座標軸中出現了數值和字符串兩種類型如何解決。
官網類似案例
兩個軸指定的都是字符串類型的數據
import plotly.figure_factory as ff
z = [[101,131,95],
[112,74,146]]
# 重點:都是字符串類型
x = ['Team A', 'Team B', 'Team C']
y = ['Game Two', 'Game One']
z_text = [[101,131,95],
[112,74,146]]
fig = ff.create_annotated_heatmap(
z,
x=x,
y=y,
annotation_text=z_text, # 標註文本內容
colorscale='Viridis')
fig.show()
下面是可以出圖的:
改變座標軸數據
在座標軸的數據中,同時使用數值和字符串:
這樣子就不能出圖:問題到底出在哪裏呢?
如何解決?介紹兩種方法:
方法1:通過參數設置
import plotly.figure_factory as ff
z = [[101,131,95],
[112,74,146]]
# 1、設置座標軸數據,統一用數據格式
x = list(range(0,3))
y = list(range(0,2))
z_text = [[101,131,95],
[112,74,146]]
fig = ff.create_annotated_heatmap(
z,
x=x,
y=y,
annotation_text=z_text,
colorscale='Viridis')
# 解決方法
# 實際座標軸
xticks=[1, 'Team B', 'Team C']
yticks=[1, 'Game One']
# 修改座標軸:將x用xticks來代替,y軸類似
fig.update_xaxes(tickvals=x, ticktext=xticks)
fig.update_yaxes(tickvals=y, ticktext=yticks)
fig.show()
方法2:自定義函數
import plotly.figure_factory as ff
z = [[101,131,95],
[112,74,146]]
x = [1, 'Team B', 'Team C']
y = [1, 'Game One']
# 待顯示的數據
z_text = z
# 關鍵函數:修改座標軸
def hm_axis(l):
return [f"{chr(0)+str(i)+chr(0)}" for i in l]
fig = ff.create_annotated_heatmap(
z,
x=hm_axis(x),
y=hm_axis(y),
annotation_text=z_text,
colorscale='Viridis')
fig.show()
完美解決!