(數據科學學習手札87)利用adjustText解決matplotlib文字標籤遮擋問題

本文示例代碼、數據已上傳至個人Github倉庫https://github.com/CNFeffery/DataScienceStudyNotesgit

1 簡介

  在進行數據可視化時咱們經常須要在可視化做品上進行一些文字標註,譬如對散點圖咱們能夠將每一個散點對應的屬性信息標註在每一個散點旁邊,但隨着散點量的增多,或圖像上的某個區域彙集了較多的散點時,疊加上的文字標註會擠在一塊兒相互疊置,出現如圖1所示的狀況:github

圖1

  出現這種狀況很是影響數據可視化做品的呈現效果,而咱們下面要介紹的adjustText是一個輔助matplotlib所繪製的圖像自動調整文字位置以緩解遮擋現象的庫,其靈感來源於R中很是著名的輔助ggplot2解決文字遮擋問題的ggrepel算法

圖2

  它經過算法迭代,在一輪輪的迭代過程當中逐漸消除文字遮擋現象:dom

圖3

  下面咱們就來學習如何使用adjustText解決matplotlib圖像文字遮擋問題。函數

2 使用adjustText解決文字遮擋問題

2.1 從一個簡單的例子出發

  使用pip install adjustTextconda install -c conda-forge adjusttext 來安裝adjustText。安裝成功以後,首先生成隨機示例數據以方便以後的演示:學習

import matplotlib.pyplot as plt
from adjustText import adjust_text
import numpy as np

#解決中文顯示問題
plt.rcParams['font.sans-serif'] = ['SimHei']

seed = np.random.RandomState(42) # 固定隨機數水平
x, y = seed.uniform(0, 1, [2, 100]) # 產生固定的均勻分佈隨機數
texts = [f'文字{i}' for i in range(x.__len__())]

  接着咱們先不使用adjustText調整圖像,直接繪製出原始的散點+文字標籤3d

fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(x, y, c='SeaGreen', s=10) # 繪製散點

# 繪製全部點對應的文字標籤
for x_, y_, text in zip(x, y, texts):
    plt.text(x_, y_, text, fontsize=12)

# 美觀起見隱藏頂部與右側邊框線
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

fig.savefig('圖4.png', dpi=300, bbox_inches='tight', pad_inches=0) # 保存圖像
圖4

  能夠看到,在一般的狀況下,散點彙集的區域內文字標籤很是容易重疊在一塊兒,接下來咱們使用adjustText的基礎功能來消除文字重疊現象:code

圖5

  這時能夠看到與圖4相比,圖5中的全部文字都沒有出現彼此重疊現象,adjustText幫助咱們自動微調了文字的擺放位置,而且距離原始散點偏移較大的文字還貼心的加上了鏈接線,至此,咱們就初探了adjustText的強大功能,接下來咱們來學習adjustText的更多功能。orm

2.2 adjust_text的用法

  adjustText中的核心功能都經過調用函數adjust_text來實現,其核心參數以下:對象

texts:List型,每一個元素都是表示單個文字標籤對應的matplotlib.text.Text對象

ax:繪製文字標籤的目標axe對象,默認爲最近一次的axe對象

lim:int型,控制迭代調整文本標籤位置的次數,默認爲500次

precision:float型,用於決定迭代中止的精度,默認爲0.01,即全部標籤相互遮擋部分的長和寬佔全部標籤自身長寬之和的比例,addjust_text會在精度達到precision和迭代次數超過lim這兩個條件中至少有一個知足時中止迭代

only_move:字典型,用於指定文本標籤與不一樣對象發生遮擋時的位移策略,鍵有'points''text''objects',對應的值可選'xy''x''y',分別表明豎直和水平方向均調整、只調整水平方向以及只調整豎直方向

arrowprops:字典型,用於設置偏移後的文字標籤與原始位置之間的連線樣式,下文會做具體演示

save_steps:bool型,用於決定是否保存記錄迭代過程當中各輪的幀圖像,默認爲False

save_prefix:str型,當save_steps設置爲True時,用於指定中間幀保存的路徑,默認爲'',即當前工做路徑

  下面咱們來演示一下這些參數的使用效果,首先咱們來看看only_move參數的效果,在圖6的基礎上,咱們設置only_move={'text': 'x'},即當文字出現遮擋時,只在水平方向上進行偏移,這裏將save_steps設置爲True以直觀地查看偏移過程:

fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(x, y, c='SeaGreen', s=10) # 繪製散點

# 使用adjustText修正文字重疊現象
new_texts = [plt.text(x_, y_, text, fontsize=12) for x_, y_, text in zip(x, y, texts)]
adjust_text(new_texts, 
            only_move={'text': 'x'},
            arrowprops=dict(arrowstyle='-', color='grey'),
            save_steps=True)

# 美觀起見隱藏頂部與右側邊框線
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
圖6

  能夠看到在整個迭代微調的過程當中,每一個標籤只在水平方向發生位移,你能夠根據本身做圖的實際須要靈活調整這裏的平移策略。接下來咱們來看看arrowprops對可視化結果的影響,在以前的例子裏咱們設置了arrowprops={arrowstyle='-', color='grey'},其中arrowstyle用於設定連線的線型,color不用多說,接下來咱們添加參數lw用於控制線的寬度,並對線型與顏色進行修改:

fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(x, y, c='SeaGreen', s=10) # 繪製散點

# 使用adjustText修正文字重疊現象
new_texts = [plt.text(x_, y_, text, fontsize=12) for x_, y_, text in zip(x, y, texts)]
adjust_text(new_texts, 
            arrowprops=dict(arrowstyle='->', 
                            color='red',
                            lw=1))

# 美觀起見隱藏頂部與右側邊框線
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

fig.savefig('圖7.png', dpi=300, bbox_inches='tight', pad_inches=0) # 保存圖像

  這時連線隨着咱們自定義的設置改變到相應的樣式:

圖7

  有關adjustText的更多參數設置信息和示例能夠去官方文檔(https://adjusttext.readthedocs.io/en/latest/ )查看。

  以上就是本文的所有內容,若有疑問歡迎在評論區與咱們討論。

相關文章
相關標籤/搜索