1. 程式人生 > >matplotlib8 -- 文字註釋進一步詳解 bbox引數, 箭頭形狀等

matplotlib8 -- 文字註釋進一步詳解 bbox引數, 箭頭形狀等

在matplotlib7中說明了,除了描述箭頭屬性的引數,其餘傳入annotate函式的引數,都將解釋為text的屬性引數。

1. text的bbox屬性 以及其他的屬性

描述Text的屬性,包括顏色,字型大小,字型型別等
matplotlib.text.Text

著重講述一下字典屬性bbox
簡單的說就是在用不同的矩形框將文字框起來,並用一系列屬性來定義矩形框的

  • boxstyle : 矩形框的型別
  • alpha: [0, 1] 透明度,0為完全透明,1為完全不透明
import numpy.random
import matplotlib.pyplot as
plt fig = plt.figure(1, figsize=(5,5)) fig.clf() ax = fig.add_subplot(111) ax.set_aspect(1) x1 = -1 + numpy.random.randn(100) y1 = -1 + numpy.random.randn(100) x2 = 1. + numpy.random.randn(100) y2 = 1. + numpy.random.randn(100) ax.scatter(x1, y1, color="r") ax.scatter(x2, y2, color="g") # 設定Sample A/B的bbox
bbox_props = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9) ax.text(-2, -2, "Sample A", ha="center", va="center", size=20, bbox=bbox_props) ax.text(2, 2, "Sample B", ha="center", va="center", size=20, bbox=bbox_props) # 設定Direction Text的bbox bbox_props = dict(boxstyle="rarrow", fc=
(0.8,0.9,0.9), ec="b", lw=2) t = ax.text(0, 0, "Direction", ha="center", va="center", rotation=45, size=15, bbox=bbox_props) # 通過text物件的get_bbox_patch方法可以得到bbox物件,利用set_*方法設定屬性 bb = t.get_bbox_patch() bb.set_boxstyle("rarrow", pad=0.6) ax.set_xlim(-4, 4) ax.set_ylim(-4, 4) plt.draw() plt.show()

在這裡插入圖片描述

  1. matplotlib7中有一張圖,可以看出tick的label看不清楚了,通過label中的set_*方法可以對字型以及透明度重新設定
    在這裡插入圖片描述
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi, np.pi, 128,endpoint=True)
cosx,sinx,x_3 = np.cos(x), np.sin(x), x / 3

#%%
fig = plt.figure(1)
axes0 = plt.subplot(111)
line1, line2 = axes0.plot(x, cosx, 'r',x, sinx, 'c')

line1.set_linewidth(2.5)
line2.set_linewidth(1)
# plt.xlim(x.min() *2, x.max()*2)
axes0.set_xlim(x.min() *1.2, x.max()*1.2)
axes0.set_ylim(cosx.min() * 1.2, cosx.max() * 1.2)

axes0.set_xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
axes0.set_xticklabels([r'$-\pi$', r'$-\frac{\pi}{2}$', 0,  r'$+\frac{\pi}{2}$', r'$+\pi$'])
axes0.set_yticks([-1, 0, 1])
axes0.set_yticklabels([r'-1', r'0', r'+1'])

# add legend
axes0.legend([line1, line2], ['y=cos(x)', 'y=sin(x)'])

# 軸居中
axes0.spines['right'].set_color('none')
axes0.spines['top'].set_color('none')
axes0.xaxis.set_ticks_position('bottom')
axes0.spines['bottom'].set_position(('data',0))
axes0.yaxis.set_ticks_position('left')
axes0.spines['left'].set_position(('data',0))
# 添加註釋
t = 2 * np.pi / 3

# 通過新增散點來是的圖更好看[t,0], [t, 0.01],  ....[t, np.sin(t)]
axes0.plot([t, t], [0, np.sin(t)], color='c', linewidth=1.5, linestyle="--")
axes0.scatter([t],[np.sin(t)] ,s=50, c='c')
axes0.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
              xy=(t, np.sin(t)), xycoords='data',
              xytext=(+10, +30), textcoords='offset points',
              fontsize=16, color= 'c',
              arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

# 同樣對cosx做處理
axes0.plot([t, t], [0, np.cos(t)], color='r', linewidth=1.5, linestyle="--")
axes0.scatter([t],[np.cos(t)] ,s=50, c='r')
axes0.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
              xy=(t, np.cos(t)), xycoords='data',
              xytext=(-90, -50), textcoords='offset points',
              fontsize=16, color= 'r',
              arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

# newly code added 
for label in axes0.get_xticklabels() + axes0.get_yticklabels():
    label.set_fontsize(16)
    label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.9 ))


plt.show()

在這裡插入圖片描述

2. 設定箭頭屬性

  • arrowprops 字典屬性

箭頭建立過程如下:

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

x1, y1 = 0.3, 0.3
x2, y2 = 0.7, 0.7

fig = plt.figure(1, figsize=(8,3))

from mpl_toolkits.axes_grid.axes_grid import AxesGrid
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText

#from matplotlib.font_manager import FontProperties

def add_at(ax, t, loc=2):
    fp = dict(size=10)
    _at = AnchoredText(t, loc=loc, prop=fp)
    ax.add_artist(_at)
    return _at


grid = AxesGrid(fig, 111, (1, 4), label_mode="1", share_all=True)

grid[0].set_autoscale_on(False)

ax = grid[0]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
'''
add code to plot arrow
'''

plt.draw()
plt.show()

在這裡插入圖片描述

接下來只貼建立過程中的引數程式碼

  1. 在兩點之間建立一條連線路徑,通過引數connectionstyle控制
ax.annotate("",
            xy=(x1, y1), xycoords='data',
            xytext=(x2, y2), textcoords='data',
            arrowprops=dict(arrowstyle="-", #linestyle="dashed",
                            color="0.5",
                            patchB=None,
                            shrinkB=0,
                            connectionstyle="arc3,rad=0.3",
                            ),
            )

add_at(ax, "connect", loc=2)

在這裡插入圖片描述

  1. 如果給出patch物件(patchA或patchB),路徑會省略掉一部分防止與patch物件交疊
ax.annotate("",
            xy=(x1, y1), xycoords='data',
            xytext=(x2, y2), textcoords='data',
            arrowprops=dict(arrowstyle="-", #linestyle="dashed",
                            color="0.5",
                            patchB=None,
                            shrinkB=0,
                            connectionstyle="arc3,rad=0.3",
                            ),
            )

add_at(ax, "connect", loc=2)

在這裡插入圖片描述

  1. 接下通過shrinkA,shrinkB引數確定與patch邊緣的距離
ax.annotate("",
            xy=(x1, y1), xycoords='data',
            xytext=(x2, y2), textcoords='data',
            arrowprops=dict(arrowstyle="-", #linestyle="dashed",
                            color="0.5",
                            patchB=el,
                            shrinkB=5,
                            connectionstyle="arc3,rad=0.3",
                            ),
            )

add_at(ax, "shrink", loc=2)

在這裡插入圖片描述

  1. 最後通過arrowstyle引數確定arrow的形狀
ax.annotate("",
            xy=(x1, y1), xycoords='data',
            xytext=(x2, y2), textcoords='data',
            arrowprops=dict(arrowstyle="fancy", #linestyle="dashed",
                            color="0.5",
                            patchB=el,
                            shrinkB=5,
                            connectionstyle="arc3,rad=0.3",
                            ),
            )

add_at(ax, "mutate", loc=2)

在這裡插入圖片描述

關於connectionstyle,
示例程式碼以及圖片:


import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

fig = plt.figure(1, figsize=(8,5))
fig.clf()
from mpl_toolkits.axes_grid.axes_grid import AxesGrid
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText

#from matplotlib.font_manager import FontProperties

def add_at(ax, t, loc=2):
    fp = dict(size=8)
    _at = AnchoredText(t, loc=loc, prop=fp)
    ax.add_artist(_at)
    return _at


grid = AxesGrid(fig, 111, (3, 5), label_mode="1", share_all=True)

grid[0].set_autoscale_on(False)


x1, y1 = 0.3, 0.3
x2, y2 = 0.7, 0.7


def demo_con_style(ax, connectionstyle, label=None):

    if label is None:
        label = connectionstyle

    x1, y1 = 0.3, 0.2
    x2, y2 = 0.8, 0.6

    ax.plot([x1, x2], [y1, y2], ".")
    ax.annotate("",
                xy=(x1, y1), xycoords='data',
                xytext=(x2, y2), textcoords='data',
                arrowprops=dict(arrowstyle="->", #linestyle="dashed",
                                color="0.5",
                                shrinkA=5, shrinkB=5,
                                patchA=None,
                                patchB=None,
                                connectionstyle=connectionstyle,
                                ),
                )

    add_at(ax, label, loc=2)

column = grid.axes_column[0]

demo_con_style(column[0], "angle3,angleA=90,angleB=0",
               label="angle3,\nangleA=90,\nangleB=0")
demo_con_style(column[1], "angle3,angleA=0,angleB=90",
               label="angle3,\nangleA=0,\nangleB=90")



column = grid.axes_column[1]

demo_con_style(column[0], "arc3,rad=0.")
demo_con_style(column[1], "arc3,rad=0.3")
demo_con_style(column[2], "arc3,rad=-0.3")



column = grid.axes_column[2]

demo_con_style(column[0], "angle,angleA=-90,angleB=180,rad=0",
               label="angle,\nangleA=-90,\nangleB=180,\nrad=0")
demo_con_style(column[1], "angle,angleA=-90,angleB=180,rad=5",
               label="angle,\nangleA=-90,\nangleB=180,\nrad=5")
demo_con_style(column[2], "angle,angleA=-90,angleB=10,rad=5",
               label="angle,\nangleA=-90,\nangleB=10,\nrad=0")


column = grid.axes_column[3]

demo_con_style(column[0], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=0",
               label="arc,\nangleA=-90,\nangleB=0,\narmA=30,\narmB=30,\nrad=0")
demo_con_style(column[1], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5",
               label="arc,\nangleA=-90,\nangleB=0,\narmA=30,\narmB=30,\nrad=5")
demo_con_style(column[2], "arc,angleA=-90,angleB=0,armA=0,armB=40,rad=0",
               label="arc,\nangleA=-90,\nangleB=0,\narmA=0,\narmB=40,\nrad=0")


column = grid.axes_column[4]

demo_con_style(column[0], "bar,fraction=0.3",
               label="bar,\nfraction=0.3")
demo_con_style(column[1], "bar,fraction=-0.3",
               label="bar,\nfraction=-0.3")
demo_con_style(column[2], "bar,angle=180,fraction=-0.2",
               label="bar,\nangle=180,\nfraction=-0.2")


#demo_con_style(column[1], "arc3,rad=0.3")
#demo_con_style(column[2], "arc3,rad=-0.3")


grid[0].set_xlim(0, 1)
grid[0].set_ylim(0, 1)
grid.axes_llc.axis["bottom"].toggle(ticklabels=False)
grid.axes_llc.axis["left"].toggle(ticklabels=False)
fig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95)

plt.draw()
plt.show()

在這裡插入圖片描述

關於arrowstyle

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

styles = mpatches.ArrowStyle.get_styles()

ncol = 2
nrow = (len(styles) + 1) // ncol
figheight = (nrow + 0.5)
fig1 = plt.figure(1, (4.*ncol/1.5, figheight/1.5))
fontsize = 0.2 *