不要迷信默认设置

导入相关的包:

In [1]:

  1. import numpy as np
  2. import matplotlib.pyplot as plt

生成三角函数:

In [2]:

  1. x = np.linspace(-np.pi, np.pi)
  2. c, s = np.cos(x), np.sin(x)

默认绘图

In [3]:

  1. %matplotlib inline
  2.  
  3. # 画图
  4. p = plt.plot(x,c)
  5. p = plt.plot(x,s)
  6.  
  7. # 在脚本中需要加上这句才会显示图像
  8. plt.show()

06.09 不要迷信默认设置 - 图1

默认效果如图所示,我们可以修改默认的属性来得到更漂亮的结果。

图像以 Figure # 为窗口标题,并且数字从 1 开始,figure() 函数的主要参数如下:

参数 默认值 描述
num 1 图号
figsize figure.figsize 图大小(宽,高)(单位英寸)
dpi figure.dpi 分辨率(每英寸所打印的点数)
facecolor figure.facecolor 背景颜色
edgecolor figure.edgecolor 边界颜色
frameon True 是否显示图框架

In [ ]:

  1. # 设置图像大小
  2. f = plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图
  5. p = plt.plot(x,c)
  6. p = plt.plot(x,s)
  7.  
  8. # 在脚本中需要加上这句才会显示图像
  9. plt.show()

设置线条颜色,粗细,类型

首先,我们使用 figure() 函数来创建一幅新图像,并且指定它的大小,使得长宽比更合适。

然后,我们使用 color, linewidth, linestyle 参数,指定曲线的颜色,粗细,类型:

In [4]:

  1. # 设置图像大小
  2. f = plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. p = plt.plot(x, c, color="blue", linewidth=2.5, linestyle="-")
  6. p = plt.plot(x, s, color="red", linewidth=2.5, linestyle="-")
  7.  
  8. # 在脚本中需要加上这句才会显示图像
  9. # plt.show()

06.09 不要迷信默认设置 - 图2

也可以像 Matlab 中一样使用格式字符来修改参数:

表示颜色的字符参数有:

字符 颜色
‘b’ 蓝色,blue
‘g’ 绿色,green
‘r’ 红色,red
‘c’ 青色,cyan
‘m’ 品红,magenta
‘y’ 黄色,yellow
‘k’ 黑色,black
‘w’ 白色,white

表示类型的字符参数有:

字符 类型 字符 类型
'-' 实线 '—' 虚线
'-.' 虚点线 ':' 点线
'.' ',' 像素点
'o' 圆点 'v' 下三角点
'^' 上三角点 '<' 左三角点
'>' 右三角点 '1' 下三叉点
'2' 上三叉点 '3' 左三叉点
'4' 右三叉点 's' 正方点
'p' 五角点 '*' 星形点
'h' 六边形点1 'H' 六边形点2
'+' 加号点 'x' 乘号点
'D' 实心菱形点 'd' 瘦菱形点
'_' 横线点

In [5]:

  1. # 设置图像大小
  2. f = plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. p = plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. # 在脚本中需要加上这句才会显示图像
  9. # plt.show()

06.09 不要迷信默认设置 - 图3

设置横轴纵轴的显示区域

我们希望将坐标轴的显示区域放大一些,这样可以看到所有的点,可以使用 plt 中的 xlimylim 来设置:

In [6]:

  1. # 设置图像大小
  2. p = plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. p = plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. ########################################################################
  9.  
  10. # 设置显示范围
  11. p = plt.xlim(x.min() * 1.1, x.max() * 1.1)
  12. p = plt.ylim(c.min() * 1.1, c.max() * 1.1)
  13.  
  14. ########################################################################
  15.  
  16. # 在脚本中需要加上这句才会显示图像
  17. # plt.show()

06.09 不要迷信默认设置 - 图4

设置刻度

对于三教函数来说,我们希望将 x 轴的刻度设为与 $\pi$ 有关的点,可以使用 plt 中的 xticksyticks 函数,将需要的刻度传入:

In [7]:

  1. # 设置图像大小
  2. f = plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. p = plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. # 设置显示范围
  9. plt.xlim(x.min() * 1.1, x.max() * 1.1)
  10. plt.ylim(c.min() * 1.1, c.max() * 1.1)
  11.  
  12. ###########################################################################
  13.  
  14. # 设置刻度
  15. p = plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
  16. p = plt.yticks([-1, 0, 1])
  17.  
  18. ###########################################################################
  19.  
  20. # 在脚本中需要加上这句才会显示图像
  21. # plt.show()

06.09 不要迷信默认设置 - 图5

设定 x 轴 y 轴标题

我们想让刻度的位置显示的是含有 $\pi$ 的标识而不是浮点数,可以在 xticks 中传入第二组参数,这组参数代表对应刻度的显示标识。这里,我们使用 latex 的语法来显示特殊符号(使用 $$ 包围的部分):

In [8]:

  1. # 设置图像大小
  2. f = plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. p = plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. # 设置显示范围
  9. plt.xlim(x.min() * 1.1, x.max() * 1.1)
  10. plt.ylim(c.min() * 1.1, c.max() * 1.1)
  11.  
  12. # 设置刻度及其标识
  13. p = plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
  14. ['$-\pi$', '$-\pi/2$', '$0$', '$\pi/2$', '$\pi$'], fontsize ='xx-large')
  15. p = plt.yticks([-1, 0, 1],
  16. ['$-1$', '$0$', '$+1$'], fontsize ='xx-large')
  17.  
  18. # 在脚本中需要加上这句才会显示图像
  19. # plt.show()

06.09 不要迷信默认设置 - 图6

移动坐标轴的位置

现在坐标轴的位置是在边界上,而且有上下左右四条,我们现在想将下面和左边的两条移动到中间,并将右边和上面的两条去掉:

In [9]:

  1. # 设置图像大小
  2. f = plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. # 设置显示范围
  9. plt.xlim(x.min() * 1.1, x.max() * 1.1)
  10. plt.ylim(c.min() * 1.1, c.max() * 1.1)
  11.  
  12. # 得到轴的句柄
  13. ax = plt.gca()
  14. # ax.spines参数表示四个坐标轴线
  15. # 将右边和上边的颜色设为透明
  16. ax.spines['right'].set_color('none')
  17. ax.spines['top'].set_color('none')
  18.  
  19. ###################################################################################
  20.  
  21. # 将 x 轴的刻度设置在下面的坐标轴上
  22. ax.xaxis.set_ticks_position('bottom')
  23. # 设置位置
  24. ax.spines['bottom'].set_position(('data',0))
  25.  
  26. # 将 y 轴的刻度设置在左边的坐标轴上
  27. ax.yaxis.set_ticks_position('left')
  28. # 设置位置
  29. ax.spines['left'].set_position(('data',0))
  30.  
  31. ###################################################################################
  32.  
  33. # 设置刻度及其标识
  34. p = plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
  35. ['$-\pi$', '$-\pi/2$', '$0$', '$\pi/2$', '$\pi$'], fontsize ='xx-large')
  36. p = plt.yticks([-1, 0, 1],
  37. ['$-1$', '$0$', '$+1$'], fontsize ='xx-large')
  38.  
  39. # 在脚本中需要加上这句才会显示图像
  40. # plt.show()

06.09 不要迷信默认设置 - 图7

加入图例

使用 legend() 加入图例:

In [10]:

  1. # 设置图像大小
  2. plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. # 设置显示范围
  9. plt.xlim(x.min() * 1.1, x.max() * 1.1)
  10. plt.ylim(c.min() * 1.1, c.max() * 1.1)
  11.  
  12. # 得到画图的句柄
  13. ax = plt.gca()
  14.  
  15. # ax.spines参数表示四个坐标轴线
  16. # 将右边和上边的颜色设为透明
  17. ax.spines['right'].set_color('none')
  18. ax.spines['top'].set_color('none')
  19.  
  20. # 将 x 轴的刻度设置在下面的坐标轴上
  21. ax.xaxis.set_ticks_position('bottom')
  22. # 设置位置
  23. ax.spines['bottom'].set_position(('data',0))
  24.  
  25. # 将 y 轴的刻度设置在左边的坐标轴上
  26. ax.yaxis.set_ticks_position('left')
  27. # 设置位置
  28. ax.spines['left'].set_position(('data',0))
  29.  
  30. # 设置刻度及其标识
  31. plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
  32. ['$-\pi$', '$-\pi/2$', '$0$', '$\pi/2$', '$\pi$'], fontsize ='xx-large')
  33. plt.yticks([-1, 0, 1],
  34. ['$-1$', '$0$', '$+1$'], fontsize ='xx-large')
  35.  
  36. ##################################################################################################
  37.  
  38. # 加入图例,frameon表示去掉图例周围的边框
  39. l = plt.legend(['cosine', 'sine'], loc='upper left', frameon=False)
  40.  
  41. ##################################################################################################
  42.  
  43. # 在脚本中需要加上这句才会显示图像
  44. # plt.show()

06.09 不要迷信默认设置 - 图8

注释特殊点

我们可以使用 anotate 函数来注释特殊的点,假设我们要显示的点是 $2\pi/3$:

In [11]:

  1. # 设置图像大小
  2. plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. # 设置显示范围
  9. plt.xlim(x.min() * 1.1, x.max() * 1.1)
  10. plt.ylim(c.min() * 1.1, c.max() * 1.1)
  11.  
  12. # 得到画图的句柄
  13. ax = plt.gca()
  14.  
  15. # ax.spines参数表示四个坐标轴线
  16. # 将右边和上边的颜色设为透明
  17. ax.spines['right'].set_color('none')
  18. ax.spines['top'].set_color('none')
  19.  
  20. # 将 x 轴的刻度设置在下面的坐标轴上
  21. ax.xaxis.set_ticks_position('bottom')
  22. # 设置位置
  23. ax.spines['bottom'].set_position(('data',0))
  24.  
  25. # 将 y 轴的刻度设置在左边的坐标轴上
  26. ax.yaxis.set_ticks_position('left')
  27. # 设置位置
  28. ax.spines['left'].set_position(('data',0))
  29.  
  30. # 设置刻度及其标识
  31. plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
  32. ['$-\pi$', '$-\pi/2$', '$0$', '$\pi/2$', '$\pi$'], fontsize ='xx-large')
  33. plt.yticks([-1, 0, 1],
  34. ['$-1$', '$0$', '$+1$'], fontsize ='xx-large')
  35.  
  36. # 加入图例,frameon表示图例周围是否需要边框
  37. l = plt.legend(['cosine', 'sine'], loc='upper left', frameon=False)
  38.  
  39. ####################################################################################
  40.  
  41. # 数据点
  42. t = 2 * np.pi / 3
  43.  
  44. # 蓝色虚线
  45. plt.plot([t,t],[0,np.cos(t)], color ='blue', linewidth=2.5, linestyle="--")
  46.  
  47. # 该点处的 cos 值
  48. plt.scatter([t,],[np.cos(t),], 50, color ='blue')
  49.  
  50. # 在对应的点显示文本
  51. plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$', # 文本
  52. xy=(t, np.sin(t)), # 数据点坐标位置
  53. xycoords='data', # 坐标相对于数据
  54. xytext=(+10, +30), # 文本位置坐标
  55. textcoords='offset points', # 坐标相对于数据点的坐标
  56. fontsize=16, # 文本大小
  57. arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2")) # 箭头
  58.  
  59. # 红色虚线
  60. p = plt.plot([t,t],[0,np.sin(t)], color ='red', linewidth=2.5, linestyle="--")
  61.  
  62. # 该点处的 sin 值
  63. p = plt.scatter([t,],[np.sin(t),], 50, color ='red')
  64.  
  65. # 显示文本
  66. p = plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
  67. xy=(t, np.cos(t)), xycoords='data',
  68. xytext=(-90, -50), textcoords='offset points', fontsize=16,
  69. arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
  70.  
  71.  
  72. #####################################################################################
  73.  
  74. # 在脚本中需要加上这句才会显示图像
  75. # plt.show()

06.09 不要迷信默认设置 - 图9

最后调整

调整刻度值的大小,并让其显示在曲线上方。

In [12]:

  1. # 设置图像大小
  2. plt.figure(figsize=(10,6), dpi=80)
  3.  
  4. # 画图,指定颜色,线宽,类型
  5. plt.plot(x, c, 'b-',
  6. x, s, 'r-', linewidth=2.5)
  7.  
  8. # 设置显示范围
  9. plt.xlim(x.min() * 1.1, x.max() * 1.1)
  10. plt.ylim(c.min() * 1.1, c.max() * 1.1)
  11.  
  12. # 得到画图的句柄
  13. ax = plt.gca()
  14.  
  15. # ax.spines参数表示四个坐标轴线
  16. # 将右边和上边的颜色设为透明
  17. ax.spines['right'].set_color('none')
  18. ax.spines['top'].set_color('none')
  19.  
  20. # 将 x 轴的刻度设置在下面的坐标轴上
  21. ax.xaxis.set_ticks_position('bottom')
  22. # 设置位置
  23. ax.spines['bottom'].set_position(('data',0))
  24.  
  25. # 将 y 轴的刻度设置在左边的坐标轴上
  26. ax.yaxis.set_ticks_position('left')
  27. # 设置位置
  28. ax.spines['left'].set_position(('data',0))
  29.  
  30. # 设置刻度及其标识
  31. plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
  32. ['$-\pi$', '$-\pi/2$', '$0$', '$\pi/2$', '$\pi$'], fontsize ='xx-large')
  33. plt.yticks([-1, 0, 1],
  34. ['$-1$', '$0$', '$+1$'], fontsize ='xx-large')
  35.  
  36. # 加入图例,frameon表示图例周围是否需要边框
  37. l = plt.legend(['cosine', 'sine'], loc='upper left', frameon=False)
  38.  
  39. # 数据点
  40. t = 2 * np.pi / 3
  41.  
  42. # 蓝色虚线
  43. plt.plot([t,t],[0,np.cos(t)], color ='blue', linewidth=2.5, linestyle="--")
  44.  
  45. # 该点处的 cos 值
  46. plt.scatter([t,],[np.cos(t),], 50, color ='blue')
  47.  
  48. # 在对应的点显示文本
  49. plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$', # 文本
  50. xy=(t, np.sin(t)), # 数据点坐标位置
  51. xycoords='data', # 坐标相对于数据
  52. xytext=(+10, +30), # 文本位置坐标
  53. textcoords='offset points', # 坐标相对于数据点的坐标
  54. fontsize=16, # 文本大小
  55. arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2")) # 箭头
  56.  
  57. # 红色虚线
  58. p = plt.plot([t,t],[0,np.sin(t)], color ='red', linewidth=2.5, linestyle="--")
  59.  
  60. # 该点处的 sin 值
  61. p = plt.scatter([t,],[np.sin(t),], 50, color ='red')
  62.  
  63. # 显示文本
  64. p = plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
  65. xy=(t, np.cos(t)), xycoords='data',
  66. xytext=(-90, -50), textcoords='offset points', fontsize=16,
  67. arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
  68.  
  69.  
  70. #####################################################################################
  71.  
  72. for label in ax.get_xticklabels() + ax.get_yticklabels():
  73. label.set_fontsize(16)
  74. label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65 ))
  75.  
  76. ####################################################################################
  77.  
  78. # 在脚本中需要加上这句才会显示图像
  79. # plt.show()

06.09 不要迷信默认设置 - 图10

The devil is in the details.

原文: https://nbviewer.jupyter.org/github/lijin-THU/notes-python/blob/master/06-matplotlib/06.09-do-not-trust-the-defaults.ipynb