目录
简介
matplotlib的普通的axes类只能在一个框里作图,原点在左下角,对于一般的使用情况基本满足,但对于要把坐标原点移动到其它位置,或者要给坐标轴加上箭头等,就得使用axisartist类了,或者 matplotlib不用axisartist画出带箭头且原点居中的坐标系的画法。写这篇文的时候(2021.12.22)网上大概搜了一下除了官网以外基本找不着对axisartist类的详细介绍,但又需要对图片和坐标进行大量调整,只能啃官网然后写了这篇总结。
建议在看这篇文章之前已经对matplotlib各个类之间的关系有了基本的了解,或者可以先看看本文的参考资料。
对于axisartist的使用先给出官方说明 Overview of axisartist toolkit
axisartist uses a custom Axes class (derived from the Matplotlib's original Axes class). As a side effect, some commands (mostly tick-related) do not work.
Since it uses special artists, some Matplotlib commands that work on Axes.xaxis and Axes.yaxis may not work.
这里大概翻译一下,axisartist是基类Axes的一个特殊的派生类,与axes相比有较高的自由度,相应的缺点就是好多axes的库函数对axisartist都不能用,尤其是与坐标轴的刻度标签相关的函数。
axisartist类的官网例子
官网例程少了不少东西,这里把我会的补充上。
例1
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as AA
fig = plt.figure()
# [x, y, w, h], 左下角坐标(x,y),宽w,高h
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], axes_class=AA.Axes)
ax.axis["right"].set_visible(False)
ax.axis["top"].set_visible(False)
plt.show()
其中
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], axes_class=AA.Axes)
也可以写成
fig.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9)
ax = fig.add_subplot(111, axes_class=AA.Axes)
也可以写成
ax = AA.Subplot(fig, 111)
fig.add_axes(ax)
例2
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as AA
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], axes_class=AA.Axes)
ax.axis["right"].set_visible(False)
ax.axis["top"].set_visible(False)
ax.axis["left"].set_visible(False)
ax.axis["bottom"].set_visible(False)
ax.axis["y=0"] = ax.new_floating_axis(nth_coord=0, value=0)
ax.axis["right2"] = ax.new_fixed_axis(loc="right", offset=(20, 0))
plt.show()
例3
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as AA
x = np.linspace(0, 6.29, 100)
y = np.sin(x)
fig = plt.figure()
fig.subplots_adjust(left=0.06, bottom=0.01, right=0.99, top=0.99)
ax1 = fig.add_subplot(121, axes_class=AA.Axes)
ax1.axis["top", "bottom", "right"].set_visible(False)
ax1.axis["x"] = ax1.new_floating_axis(nth_coord=0, value=0)
ax1.axis["x"].label.set_text("y = 0")
ax1.set_ylim(-1.1, 1.1)
ax1.plot(x, y)
ax2 = fig.add_subplot(122, axes_class=AA.Axes)
ax2.axis["top", "bottom", "right"].set_visible(False)
ax2.axis["x"] = ax2.new_floating_axis(nth_coord=0, value=0)
ax2.axis["x"].label.set_text("Axis Zero")
ax2.set_ylim(-1.1, 1.1)
ax2.plot(x, y)
plt.show()
从正弦函数开始的新例子
从简单的例子开始
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as AA
x = np.linspace(-3.14, 3.14, 100)
y = np.sin(x)
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], axes_class=AA.Axes)
ax.axis[:].set_visible(False)
ax.axis["x"] = ax.new_floating_axis(nth_coord=0, value=0)
ax.axis["y"] = ax.new_floating_axis(nth_coord=1, value=0)
ax.plot(x, y)
plt.show()
坐标加上箭头和标题,纵坐标设置在极值点
ax.axis["y"] = ax.new_floating_axis(nth_coord=1, value=-np.pi/2)
ax.axis["x"].set_axisline_style("-|>,size=2")
ax.axis["y"].set_axisline_style("->")
ax.axis["x"].set_label('x')
ax.axis["y"].set_label('y')
修改坐标轴名字,删除箭头的蓝色,Y坐标名称方向调整
ax.axis["x"].set_label('坐标轴x')
ax.axis["y"].set_label('坐标轴y')
ax.axis["x"].line.set_color("black")
ax.axis["y"].line.set_color("black")
ax.axis["y"].set_axis_direction("left")
ax.axis["y"].label.set_axis_direction("top")
ax.axis["y"].label.set(rotation="vertical")
ax.axis["y"].major_ticklabels.set_axis_direction("left")
坐标轴字体字号,标题调整
这部分好像不能用类和库函数的方法解决,网上也没搜到什么好方法。坐标轴名称还得自己加,刻度字体字号得改默认参数。
rcparams的参数也可以在matplotlib的安装目录里改,具体见 用Python的matplotlib画图,怎么保证xlabel中中文用宋体,英文用新罗马?
Matplotlib 中英文及公式字体设置
params = {'axes.labelsize': 20, 'axes.titlesize':20, 'legend.fontsize': 20, 'xtick.labelsize': 20, 'ytick.labelsize': 20}
plt.rcParams.update(params)
ax.text(-0.5, 1.35, r'$\omega$(rad)', fontsize=20)
ax.text(3.14, -0.25, '速度(s)', fontsize=20)
由于版本更新,rcparam的参数可能会改,以下代码用于查看有哪些参数。
import matplotlib.pyplot as plt
print(plt.rcParams.keys())
调整刻度名称,完成
ax.set_xticks(np.linspace(-3, 3, 7))
ax.set_yticks(np.linspace(-1, 1, 5))
ax.set_xticklabels(['-3', '-2', '-1', '', '1', '2', '3'])
ax.set_yticklabels(['-1', '-0.5', '', '0.5', '1',])
ax.text(0.1, -0.13, '0', fontsize=20)
最后贴上全部代码
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as AA
x = np.linspace(-3.14, 3.14, 100)
y = np.sin(x)
params = {'axes.labelsize': 20, 'axes.titlesize':20, 'legend.fontsize': 20, 'xtick.labelsize': 20, 'ytick.labelsize': 20}
plt.rcParams.update(params)
fig = plt.figure()
ax = fig.add_axes([0.01, 0.01, 0.88, 0.84], axes_class=AA.Axes)
ax.axis[:].set_visible(False)
ax.axis["x"] = ax.new_floating_axis(nth_coord=0, value=0)
ax.axis["y"] = ax.new_floating_axis(nth_coord=1, value=0)
ax.axis["x"].set_axisline_style("-|>,size=2")
ax.axis["y"].set_axisline_style("-|>,size=2")
ax.axis["x"].line.set_color("black")
ax.axis["y"].line.set_color("black")
ax.axis["y"].set_axis_direction("left")
ax.axis["y"].major_ticklabels.set_axis_direction("left")
ax.set_xticks(np.linspace(-3, 3, 7))
ax.set_yticks(np.linspace(-1, 1, 5))
ax.set_xticklabels(['-3', '-2', '-1', '', '1', '2', '3'])
ax.set_yticklabels(['-1', '-0.5', '', '0.5', '1'])
ax.text(0.1, -0.13, '0', fontsize=20)
ax.text(-0.5, 1.35, r'$\omega$(rad)', fontsize=20)
ax.text(3.14, -0.25, '时间(s)', fontsize=20)
ax.plot(x, y)
plt.show()
axisartist类的常用API总结
这里实际上叫axisartist类的API不太准确,matplotlib的文档实在是过于混乱,下面总结的API不要过于认真,知道有这么个名字和功能就行。
- set_axisline_style
- set_axis_direction
附axes类的常用API总结
- set_title
- set_xlabel / set_ylabel
- set_xlim / set_ylim
- set_xticks / set_yticks
- set_xticklabels / set_yticklabels
- tick_params
- spines
- legend
axes类的简单使用
作为对照,把普通的axes类的用法放到这里。
import numpy as np
import matplotlib.pyplot as plt
1
plt.plot([1,2,3,4],[1,2,3,4])
plt.show()
2
fig=plt.figure(num=1,figsize=(4,4))
ax=fig.add_subplot(111)
ax.plot([1,2,3,4],[1,2,3,4])
plt.show()
3
fig, ax = plt.subplots()
ax.plot([1,2,3,4],[1,2,3,4])
plt.show()
参考资料
贴上其它一些对于理解matplotlib各个类之间的关系有帮助的资料。
以下代码整理自参考资料1。
import numpy as np
import matplotlib.pyplot as plt
app=[78,80,79,81,91,95,96]
ban=[70,80,81,82,75,90,89]
x=np.arange(1,8)
fig, ax = plt.subplots()
ax.set_xlim(1,7.1)
ax.set_ylim(40,100)
ax.set_xticks(np.linspace(1,7,7))
ax.set_yticks(np.linspace(50,100,6))
ax.set_xticklabels(["星期一","星期二","星期三","星期四","星期五","星期六","星期日"],fontproperties="SimHei",fontsize=12)
ax.set_yticklabels(["50kg","60kg","70kg","80kg","90kg","100kg"],fontsize=12)
ax.tick_params(left=False,pad=8,direction="in",length=2,width=3,color="b",labelsize=12)
ax.tick_params("x",labelrotation=10)
ax.spines["left"].set_color("darkblue")
ax.spines["bottom"].set_linewidth(3)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.plot(x,app,"r-.d",label='苹果')
ax.plot(x,ban,color='#008000',linestyle='-',marker='d',label="香蕉")
ax.legend(loc=3,labelspacing=2,handlelength=3,fontsize=14,shadow=True)
ax.text(7,97,"max:96",fontsize=14,color="g",alpha=1)
ax.text(6,86,"max:90",fontsize=12,alpha=1)
plt.show()