图形输出分为嵌入模式和独立窗口模式两种,在交互窗口中可用下面的两条命令控制图形的输出形式。
嵌入模式在 IPython 的交互窗口中显示图形,图形显示后不能再修改。
独立窗口模式在弹出的一个窗口中显示图形,图形可以放大、缩小和修改。(独立窗口最后一个按钮是保存图片)
import matplotlib.pyplot as plt # 导入 pyplot 模块并命名为 plt
#以下两句是魔术命令,只能在Ipython里面使用
%matplotlib inline # 设置嵌入模式显示图形
%matplotlib # 设置独立窗口模式显示图形
#Pandas 也可以绘制各类图形,调用形式为 df.plot(kind='图类型')
# %matplotlib 设置独立窗口模式
import numpy as np
import matplotlib.pyplot as plt # 导入 plt
x = np.linspace(-2, 2, 50) # 在区间[-2, 2]内等间距产生 50 个点
y = x**2 # 计算平方值
plt.plot(x,y,color='blue',ls='--',label='y=x^2') # 绘制曲线并设定蓝色、破折线、图例
plt.xlabel('x', fontsize=14) # x 轴标记字符 x
plt.ylabel('y', fontsize=14) # y 轴标记字符 y
plt.title('Example', fontsize=18) # 设置标题
plt.legend() # 显示图例(y=x^2)
方法 1:每次在程序头部设定中文字体,示例代码如下。
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定中文黑体字体
# 下面的 False 修正坐标轴上负号'-'显示为方块的问题
plt.rcParams['axes.unicode_minus'] = False
plt.xlim([-5, 5]) # 测试:坐标轴上负号显示正常
plt.title('中文标题') # 测试:中文标题显示正常
方法 2:修改 Matplotlib 配置文件以显示中文(推荐采用此方法)。此方法可在本机上一劳永逸地解决中文的显示问题,步骤如下。
#1.定位配置文件,找到该文件,打开它
import matplotlib # 导入库
matplotlib.matplotlib_fname() # 显示 matplotlib 配置文件名
#2.找到并修改文件的配置参数
#font.sans-serif : Bitstream Vera Serif, New Century Schoolbook, Century
#修改为:
font.sans-serif : SimHei, Bitstream Vera Serif, New Century Schoolbook, Century
#axes.unicode_minus : True
#修改为:
axes.unicode_minus : False
#配置后需重启Spyder才可生效
red r 红色
yellow y 黄色
black k 黑色
white w 白色
blue b 蓝色
green g 绿色
cyan c 青色
- 实线
: 虚线
-- 破折线
None 空白(不画线)
-. 点画线
o 圆圈
S(小写) 正方形
. 点
* 星号
D 菱形
d 小菱形
+ 加号
x X 号
v(小写) 一角朝下的三角形
< 一角朝左的三角形
> 一角朝右的三角形
^ 一角朝上的三角形
None 空白
best 0(默认值,自适应) 最佳
upper right 1 右上
upper left 2 左上
lower left 3 左下
lower right 4 右下
right 5 右
center left 6 左中
center right 7 右中
lower center 8 中下
upper center 9 中上
center 10 居中
plt.plot() 折线图
plt.grid(True/False) 显示/不显示网格
plt.xlim(0,5) 设置 x 轴范围
plt.ylim(0,8) 设置 y 轴范围
plt.axis('equal') 设置 x/y 轴单位长度相等
plt.axis('on/off') 显示/不显示坐标轴
plt.xlabel('x 轴') 设置 x 轴标记文字
plt.ylabel('y 轴') 设置 y 轴标记文字
plt.title('图标题') 设置图形标题
plt.legend() 显示图例
plt.text(x,y,'text') 在指定坐标处显示文字 plt.savefig('a.png') 保存图片
plt.figure(figsize=(m,n)) 设置图形大小
plt.style.use('风格') 设置绘图风格
plt.xticks(sign, ['s1','s2','s3','s4','s5'], fontsize=14) # 设置 x 轴标记文字
plt.axes([left,bottom,width,height]) #设置子图位置宽度高度
plt.plot() 折线图
plt.bar() 柱形图
plt.pie() 饼图
plt.barh() 水平条形图
plt.hist() 直方图
plt.scatter() 散点图
plt.boxplot() 箱线图
上下堆积柱形图用 bottom = plot1(某个柱形图)
左右簇状柱形图用 x + offset(偏移量)
x = []
y = []
plt.bar(x, y)
plt.legend()
#plt.show()
#水平条形图
plt.barh(x, y, hatch=' ')
plt.barh(-x, y, hatch=' ')
#限制范围
plt.ylim(0, max)/
#修改x轴标记文字
plt.xticks(x, [], fontsize=14) # 设置 x 轴标记文字
#显示y值
for sx, sy in enumerate(y):
plt.text(sx, sy+0.03, y, ha='center', fontsize=14)
#bar参数
width=宽度
color=内部填充颜色
edgecolor=边缘颜色
hatch=内部填充图案
tick_label=坐标轴标记
label=图例
bottom=以某个plt画出的图为底
x = []
labels = [] #标签
plt.pie()
plt.legend()
#设置图像大小
plt.figure(figsize=(6,9))
#设置间隔
explode=()
# autopct:百分比数字的显示格式,%.1f%%表示保留一位小数
# shadow:是否有阴影
# startangle:起始角度。默认从 0 度逆时针开始为第一块,此处选择从 90 度开始
patches, ltext, ptext = plt.pie(x, explode=explode, labels=labels,autopct='%.1f%%', shadow=False, startangle=90)
# 设置标注文字大小
for x in ltext:
x.set_size(20)
# 设置百分比文字大小
for x in ptext:
x.set_size(24)
# 设置 x/y 轴的单位长度相等
plt.axis('equal')
模板:
x = []
y = []
arg = np.polyfit(x, y, 系数)
f = np.poly1d(arg)
y2 = f(x)
plt.scatter(x, y, color=' ')
plt.plot(x, y2, color='r') # 再画拟合直线
example :
#1
np.random.seed(7) # 设置随机种子 7
x = np.random.uniform(-2, 3, 20)
y1 = 3 * x + 1 + 2 * np.random.random(20) # 生成直线点并加入随机值干扰
arg = np.polyfit(x, y1, 1) # 拟合直线,得到一次多项式的系数
f = np.poly1d(arg) # 利用系数构造拟合一次多项式
y2 = f(x) # 根据拟合的多项式计算 y2 值
plt.scatter(x, y1) # 画原始数据的散点图,见图 9.18
plt.figure() # 产生新图
plt.scatter(x, y1) # 先画原始散点图,见图 9.19
plt.plot(x, y2, color='r') # 再画拟合直线
plt.text(1, 1, f, fontsize=16) # 在坐标(1,1)处显示拟合的多项式 f
#2
N=20 # 总点数
rng = np.random.RandomState(7) # 一个随机种子为 7 的随机数生成器
x = rng.randn(N) # 生成 N 个标准正态分布小数
y = rng.randn(N)
colors = rng.rand(N)
sizes = 1000 * rng.rand(N) # 点的大小为随机值
plt.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis')
# 设置点的颜色、大小、透明度、色集
plt.colorbar() # 显示颜色条
#3
import seaborn as sns
iris = sns.load_dataset('iris') # 加载数据集
for x in [0,1]: # 循环 2 次,分别作出花萼、花瓣的散点图
if x == 0:
s = '花萼'
else:
s = '花瓣'
plt.figure() # 创建新图
plt.title('鸢尾花' + s + '长度-宽度散点图', fontsize=18)
plt.xlabel(s + '长度', fontsize=16)
plt.ylabel(s + '宽度', fontsize=16)
# 下面用字典形式规定三种花的不同标记符号
for k, v in {'setosa':'^', 'versicolor':'v', 'virginica':'o'}.items():
d = iris[iris.species==k] # 每次筛选一种花,分三次完成
plt.scatter(d.iloc[:, 2*x], d.iloc[:, 2*x+1], marker=v, s=120, label=k)
# 指定不同的 marker
plt.legend(fontsize=14)
arr参数必须,其他都是可选参数。
arr = np.random.randn(1000)
bins = [] #可设置一个区间 也可设置一个数字
plt.hist(arr, bins=10, density=0, edgecolor='b', facecolor='cyan', alpha=0.8)
#arr一维数组 bins柱子大小 density 0频数1频率
#edgecolor柱子边线颜色 facecolor直方图颜色 alpha透明度
plt.xticks(fontsize=14) # 设置 x 轴标记文字大小
plt.yticks(fontsize=14) # 设置 y 轴标记文字大小
关键的数值点:须线下限值、下四分位数(Q1)、中位数(median)、
上四分位数(Q3)、须线上限值等。
#example
arr = np.random.randn(150) # 生成 150 个标准正态分布的随机小数
arr = np.append(arr, [-3.5, 4.1]) # 特意增加两个离群点
plt.boxplot(arr) # 画箱线图,见图 9.25
arr = [-3, 0, 5, 5, 6, 7, 8, 9]
print(np.percentile(arr, [25, 50, 75])) # 输出的分位值为[3.75 5.5 7.25]
plt.boxplot(arr, showmeans=True) # True 表示要显示平均值
plt.grid(axis='y') # 显示水平格线
plt.yticks(fontsize=14) # 见图 9.26
#总结 :
#IQR = Q3 - Q1
#min = Q1 - 1.5*IQR
#MAX = Q3 + 1.5*IQR
plt.xlim(0,1) # 设 x 轴的坐标区域
plt.ylim(0,1) # 设 y 轴的坐标区域
plt.axhline(y=0.2, xmin=0.1, xmax=0.5, color='g')
# 水平线,x 轴的范围[0.1,0.5]
plt.axhline(y=0.4, xmin=0.2, xmax=0.6, color='r')
# 水平线,x 轴的范围[0.2,0.6]
plt.axvline(x=0.8, ymin=0.1, ymax=0.4, color='r')
# 垂直线,y 轴的范围[0.1,0.4]
plt.axvline(x=0.9, ymin=0.2, ymax=0.5, color='b')
# 垂直线,y 轴的范围[0.2,0.5]
plt.axhspan(ymin=0.6, ymax=0.8, xmin=0.1, xmax=0.5)
# 水平区间带
plt.axvspan(xmin=0.7, xmax=0.8, ymin=0.6, ymax=0.9)
# 垂直区间带
#核心 obj为生成的子图AxesSubplot类型 可使用plt的函数进行格式控制
obj = fig.add_subplot(行, 列, 第几个子图)
obj = plot(x, y)
#简便
# 返回一个 Figure 和一个 2x3 的 axes 数组,sharex/sharey 表示各子图使用同一个 x,y 轴刻度
fig, axes = plt.subplots(nrows=2, ncols=3, sharex=True, sharey=True)
for m in range(2):
for n in range(3): # 画 2x3 的随机直方图
axes[m, n].hist(np.random.randn(500), bins=50, color='k', alpha=0.5)
# 调整各子图的水平、垂直间距
plt.subplots_adjust(wspace=0.4, hspace=0.6)
# 直接指定子图的位置
plt.axes([left, bottom, width, height])
#example
x = np.arange(1,100)
fig = plt.figure() # 创建一个 Figure 对象
ax1 = fig.add_subplot(221) # 2 行 x2 列图形的第一个子图
ax1.plot(x, x)
ax2 = fig.add_subplot(222) # 2 行 x2 列图形的第二个子图
ax2.plot(x, -x)
ax3 = fig.add_subplot(223) # 2 行 x2 列图形的第三个子图
ax3.plot(x, x**2)
ax4 = fig.add_subplot(2, 2, 4) # 2 行 x2 列图形的第四个子图
ax4.plot(x, np.log(x))
plt.show()
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1) # 创建一个 ax 对象
ax.plot(np.random.randn(1000).cumsum()) # 随机数累加并绘制折线图
ticks = ax.set_xticks([0, 250, 500]) # x 轴上只显示 0,250,500 处的刻度
# 将上面三个刻度值用如下三个文字串显示
labels = ax.set_xticklabels(['数据一', '数据二', '数据三'], rotation=30, fontsize=14)
ax.set_title('随机数累加', fontsize=18)
ax.set_xlabel('X 轴', fontsize=18)
ax.set_ylabel('Y 轴', fontsize=18)
Matplotlib 支持 LaTeX 排版标记语言,可以方便地显示分数、根号、极限等各种数学表达式。LaTeX 标记由一对$符号包裹,内部以“\特殊字符串”的形式表达,详细情况可以访问网页https://www.latex-project.org/或 https://matplotlib.org/users/mathtext.html。
#核心
# 定义一个 box 修饰字典,设定各种格式(前景色、边线颜色、边框类型)
box = {'facecolor':'0.75', 'edgecolor':'k', 'boxstyle':'round'}
plt.text(3, 7.5, 'Third', bbox = box)
# for 循环给每个点加标记
for label, xpos, ypos in zip(labels, x, y):
plt.annotate(label, fontsize=16,
xy=(xpos, ypos), # 指明标记文字的坐标位置,见图 9.36
xytext=(6, -5), # 但要有轻微偏离;向右(6),向下(-5)
textcoords='offset points') # 此属性表示 xytext 是相对 xy 偏离的
#example
plt.text(1, 1.5, 'first') # 在(1, 1.5)处显示 first
plt.text(2, 4.5, 'second') # 在(2, 4.5)处显示 second
plt.annotate('顶部',xytext=(3.5, 1), # 文字位置
xy=(np.pi/2, 1), # 箭头位置的坐标
arrowprops={'facecolor' : 'black', 'shrink' : 0.05}) # 箭头外观
plt.xlim([0, 10])
plt.ylim([0, 10])
plt.text(1, 9, r'希腊字母$\alpha > \beta$', fontsize=14) # LaTeX 语法$标记符号$
plt.text(1, 7, r'下标$\alpha_i > \beta_i$', fontsize=14)
plt.text(1, 5, r'上标$s^2+y^3$', fontsize=14)
plt.text(1, 3, r'分数 $\frac{2}{3}$', fontsize=14)
plt.text(1, 1, r'平方根 $\sqrt{x^2 + y^2}$', fontsize=14)
plt.text(5, 9, r'求和符号$\sum_{i=0}^\infty x_i$', fontsize=12)
plt.text(5, 7, r'开 n 次方$\sqrt[3]{x}$', fontsize=16)
plt.text(5, 5, r'$sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$', fontsize=12)
plt.text(5, 3, r'积分$\int_a^b f(x)\mathrm{d}x$', fontsize=12)
def format_spines(): # 将坐标原点设置在图中央
ax = plt.gca() # gca 代表当前坐标轴
ax.spines['right'].set_color('none') # 隐藏坐标轴右侧的边线
ax.spines['top'].set_color('none') # 隐藏坐标轴顶部的边线
ax.spines['bottom'].set_position(('data', 0)) # 下边线移到 0 位置,X 轴
ax.spines['left'].set_position(('data', 0)) # 左边线移到 0 位置,Y 轴
x = np.linspace(-np.pi, np.pi, 100)
plt.plot(x, np.sin(x), color='r', label='sin(x)')
plt.plot(x, np.cos(x), color='b', label='cos(x)')
xlabels = (r'$-\pi$', r'$-\pi/2$', r'$+\pi/2$', r'$+\pi$') # LaTeX 语法
plt.xticks((-np.pi, -np.pi/2, np.pi/2, np.pi), xlabels) # 修改 x 轴刻度显示
plt.yticks([-1, -0.5, 0, 0.5, 1])
plt.legend(loc='upper left') # 见图 9.38
plt.tick_params(axis='both', labelsize=14) # 设定轴上刻度的文字大小
format_spines() # 调用自定义函数设坐标轴
fill_between(x 轴区域, y 轴起点,y 轴终点, color='填充色', alpha=透明度)
#当前的图表和子图可以使用plt.gcf()和plt.gca()获得
ax = plt.gca() #得到子图
ax.plot()
plt.gca().add_patch(plt.Rectangle((左下角坐标), 长, 宽))
x = []
y = []
pows = 1
arg = np.polyfit(x, y, pows)
f = np.poly1d(arg)
plt.scatter(x, y)
plt.plot(x, f(x), color='r')