Visualization [CHI]

2019_Lec06_visualization

画图基础

画图参考 matplotlib

In [1]:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
#import warnings; warnings.simplefilter('ignore')
# import seaborn as sns; sns.set()
%matplotlib inline

One-Dimensional Data Set

  • 随机数
In [2]:
np.random.seed(1000)
y = np.random.standard_normal(20) 
  • 画图
In [3]:
x = range(len(y))
plt.plot(x, y)
# tag: matplotlib_0
# title: Plot given x- and y-values
Out[3]:
[<matplotlib.lines.Line2D at 0x174f30e0b38>]
  • 增加网格,让坐标紧凑
In [4]:
plt.plot(y.cumsum())
plt.grid(True)  # adds a grid
plt.axis('tight')  # adjusts the axis ranges
# tag: matplotlib_3_a
# title: Plot with grid and tight axes
Out[4]:
(-0.9500000000000001, 19.95, -2.322818663749045, 0.5655085808655865)

修改坐标起始点

In [5]:
plt.plot(y.cumsum())
plt.grid(True)
plt.xlim(-1, 20)
plt.ylim(np.min(y.cumsum()) - 1,
         np.max(y.cumsum()) + 1)
# tag: matplotlib_3_b
# title: Plot with custom axes limits
Out[5]:
(-3.1915310617211072, 1.4342209788376488)
  • 设置图形大小,设置线点性状、颜色、宽度
  • 设置图形横坐标,纵坐标标题
In [6]:
plt.figure(figsize=(7, 4))
  # the figsize parameter defines the
  # size of the figure in (width, height)
plt.plot(y.cumsum(), 'b', lw=1.5)
plt.plot(y.cumsum(), 'ro')
plt.grid(True)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
# tag: matplotlib_4
# title: Plot with typical labels
Out[6]:
Text(0.5,1,'A Simple Plot')

Two-Dimensional Data Set

In [7]:
np.random.seed(2000)
y = np.random.standard_normal((20, 2)).cumsum(axis=0)
In [8]:
plt.figure(figsize=(7, 4))
#颜色自动匹配
plt.plot(y, lw=1.5)
  # plots two lines
plt.plot(y, 'ro')
  # plots two dotted lines
plt.grid(True)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
# tag: matplotlib_5
# title: Plot with two data sets
Out[8]:
Text(0.5,1,'A Simple Plot')
  • 添加题注
In [9]:
plt.figure(figsize=(7, 4))
plt.plot(y[:, 0], lw=1.5, label='1st')
plt.plot(y[:, 1], lw=1.5, label='2nd')
plt.plot(y, 'ro')
plt.grid(True)
plt.legend(loc=0)
#loc=0,best
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
# tag: matplotlib_6
# title: Plot with labeled data sets
Out[9]:
Text(0.5,1,'A Simple Plot')
In [10]:
y[:, 0] = y[:, 0] * 100
plt.figure(figsize=(7, 4))
plt.plot(y[:, 0], lw=1.5, label='1st')
plt.plot(y[:, 1], lw=1.5, label='2nd')
plt.plot(y, 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
# tag: matplotlib_7
# title: Plot with two differently scaled data sets
Out[10]:
Text(0.5,1,'A Simple Plot')
In [11]:
fig, ax1 = plt.subplots()
plt.plot(y[:, 0], 'b', lw=1.5, label='1st')
plt.plot(y[:, 0], 'ro')
plt.grid(True)
plt.legend(loc=8)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value 1st')
plt.title('A Simple Plot')
ax2 = ax1.twinx()
#共享横坐标,独立的纵坐标,坐标标在右边

plt.plot(y[:, 1], 'g', lw=1.5, label='2nd')
plt.plot(y[:, 1], 'ro')
plt.legend(loc=0)
plt.ylabel('value 2nd')
# tag: matplotlib_8
# title: Plot with two data sets and two y-axes
Out[11]:
Text(0,0.5,'value 2nd')
In [12]:
plt.figure(figsize=(7, 5))
plt.subplot(211)
plt.plot(y[:, 0], lw=1.5, label='1st')
plt.plot(y[:, 0], 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.ylabel('value')
plt.title('A Simple Plot')
plt.subplot(212)
plt.plot(y[:, 1], 'g', lw=1.5, label='2nd')
plt.plot(y[:, 1], 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
# tag: matplotlib_9
# title: Plot with two sub-plots
Out[12]:
Text(0,0.5,'value')
  • plt.subplot()分割指定画图区域
In [13]:
plt.figure(figsize=(9, 4))
plt.subplot(221)
plt.plot(y[:, 0], lw=1.5, label='1st')
plt.plot(y[:, 0], 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('1st Data Set')
plt.subplot(224)
plt.bar(np.arange(len(y)), y[:, 1], width=0.5,
        color='g', label='2nd')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.xlabel('index')
plt.title('2nd Data Set')
# tag: matplotlib_10
# title: Plot combining line/point sub-plot with bar sub-plot
# size: 80
Out[13]:
Text(0.5,1,'2nd Data Set')

Other Plot Styles

In [14]:
y = np.random.standard_normal((1000, 2))
  • 散点图
In [15]:
plt.figure(figsize=(7, 5))
plt.plot(y[:, 0], y[:, 1], 'ro')
plt.grid(True)
plt.xlabel('1st')
plt.ylabel('2nd')
plt.title('Scatter Plot')
# tag: matplotlib_11_a
# title: Scatter plot via +plot+ function
Out[15]:
Text(0.5,1,'Scatter Plot')
  • 可以直接用plt.scatter函数
In [16]:
plt.figure(figsize=(7, 5))
plt.scatter(y[:, 0], y[:, 1], marker='o')
plt.grid(True)
plt.xlabel('1st')
plt.ylabel('2nd')
plt.title('Scatter Plot')
# tag: matplotlib_11_b
# title: Scatter plot via +scatter+ function
Out[16]:
Text(0.5,1,'Scatter Plot')
  • plt.scatter可以指定颜色
In [17]:
c = np.random.randint(0, 10, len(y))
In [18]:
plt.figure(figsize=(7, 5))
plt.scatter(y[:, 0], y[:, 1], c=y[:, 1], marker='o')
plt.colorbar()
plt.grid(True)
plt.xlabel('1st')
plt.ylabel('2nd')
plt.title('Scatter Plot')
# tag: matplotlib_11_c
# title: Scatter plot with third dimension
Out[18]:
Text(0.5,1,'Scatter Plot')
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaEAAAFNCAYAAACpLtA7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzsnXd4HNX1v987s029S5ar3Au2KTZgeicQIIF0AgRSgCSElC8JaSSkhxB+CUkgJJSEFkKoobdgbFPce7flIluWbPWy2jI7M/f3x6xWWu2qWbJWMvd9nnmsnXLnzHh3zpx7P+dcIaVEoVAoFIpUoKXaAIVCoVB8eFFOSKFQKBQpQzkhhUKhUKQM5YQUCoVCkTKUE1IoFApFylBOSKFQKBQpQzkhhWKIEEL8TAjxeKrtUCiGE8oJKYYdQojThRAfCCGahRANQoj3hRAnDrDN64QQ73VZ97AQ4lcDszbhPA8LIQwhhD9q+1tCiBmH0c5eIcT5g2mbQjEcUU5IMawQQmQDLwN/AfKBMcDPgXAq7UqGEMLVzaY7pZSZwFigBnh4yIxSKEYYygkphhvTAKSU/5ZSWlLKoJTyTSnlhvYdhBDXCyG2CiFahRBbhBAnRNf/QAixq9P6K6LrZwJ/A06JRihNQogbgKuAW6PrXoruO1oI8awQolYIsUcI8c1O5/2ZEOIZIcTjQogW4LqeLkRKGQCeAGYn2y6E+JgQYnPUnkVROxFCPAaMB16K2nbr4d1KhWL4o5yQYrixA7CEEI8IIS4WQuR13iiE+DTwM+ALQDbwMaA+unkXcAaQgxM9PS6EKJVSbgW+CiyVUmZKKXOllPcD/yIatUgpLxNCaMBLwHqcCOw84NtCiI90MuHjwDNAbvT4bhFCZOI4urVJtk0D/g18GygCXsVxOh4p5TXAPuCyqG139n7bFIqRiXJCimGFlLIFOB2QwANArRDiRSFESXSXr+A4jpXSoVxKWRE99mkpZZWU0pZS/gfYCZzUj9OfCBRJKX8hpTSklLujNnyu0z5LpZT/jZ4j2E073xVCNAHlQCbJI6bPAq9IKd+SUkaAu4A04NR+2KtQjHi669NWKFJGNHK5DiA6qP84cDdwJTAOJ+JJQAjxBeD/gLLoqkygsB+nngCMjjqQdnTg3U6f9/ehnbuklLf1ss9ooKL9g5TSFkLsx4nAFIoPDcoJKYY1UsptQoiHgRujq/YDk7vuJ4SYgBO1nIcTrVhCiHWAaG8qWfNdPu8H9kgpp/ZkUj/M74kqYE77ByGEwHGwBwb5PArFsEZ1xymGFUKIGUKIW4QQY6Ofx+FEQMuiuzyI0901TzhMiTqgDJwHd230uC8SLwg4BIwVQni6rJvU6fMKoEUI8X0hRJoQQhdCzB6oPLwbngIuEUKcJ4RwA7fgKAA/6MY2heKoRDkhxXCjFTgZWC6EaMNxPptwHtJIKZ8Gfo2jOmsF/gvkSym3AP8PWIrzAJ8DvN+p3YXAZuCgEKIuuu4hYFZUnfZfKaUFXAYcB+wB6nCcXs5gX6SUcjtwNY4UvS563suklEZ0l98Ct0Vt++5gn1+hGC4INamdQqFQKFKFioQUCoVCkTKUE1IoFApFylBOSKFQKBQpQzkhhUKhUKQM5YQUCoVCkTJGVLJqYWGhLCsrG1AbbW1tZGRkDI5BQ4iye+gZqbYru4eewbB99erVdVLKokEyiY+ckyHrG6z+27Eh/IaU8qLBsqM3RpQTKisrY9WqVQNqY9GiRZx99tmDY9AQouweekaq7cruoWcwbBdCVPS+V9+pb7BY8cb4fh+nl+7sT6mrATOinJBCoVAo+oYEbOxUm9ErygkpFArFUYnEksoJKRQKhSIFOJHQ8K+Io5yQQqFQHKWo7jiFQqFQpASJxBoBtUGVE1IoFIqjFNUdp1AoFIqUIAFLOSGFQjH02Nj+ByH8NmiFiIwvIDxHYl4+xXBHRUIKhWJIkbYfzHLw/wVnolaQ4SXIrO+hZVydWuMUQ4qEQR8TEkL4gCWAF8d/PCOlvH0gbaracQrFUYQMPAGYtDsghyC03om021JklSJV2Iex9EIYOFdKeSzODMQXCSEWDMRG5YQUiqOJ8NskfZQIF0Q2Dbk5itQhkViHsfTYpoM/+tEdXQYUbiknpFAcTWgFyddLC7TcobVFkVokWIex9IYQQhdCrANqgLeklMsHYqZyQgrFUYRIv5bEn7UG+lhwTUuFSYoU4VRMOKzuuEIhxKpOyw1x7UppSSmPA8YCJwkhZg/ETiVMUCiOIoT3ZNAqAZ/TBYcF2hhE/gMIIVJtnmJIEVgc1v95nZRyfm87SSmbhBCLgIuAw+7rVU5IoTja0AoQxR84Y0BaLrimKwf0IUQC9iArtIUQRUAk6oDSgPOB3w2kTeWEFIqjEKFlgndAoiXFUcBhRkI9UQo8IoTQcfp9n5JSvjyQBpUTUigUCkWfkFJuAI4fzDaVE1IoFIqjEKdsz/DvhlVOSKFQKI5SbKmckGKEYtutNLf+nUDwZYSWQXbml8lIu0INcCsUIwQVCfXCkahBpBgcbDtAVc3FmGYl7eVf6hu3EQ6voiDvN6k1TqFQ9AmJwBoBqaCptHDQaxApBgd/4Fksq5rO9cekDOBveyLqmBQKxUjAlqLfy1CTskhISimBQa1BpBgcQqFFSBlI3CDchI01uFxjh94ohULRL1R3XB+Ias1XA1OAewdag0gxOOiusThfDbPLFomuF6XAIoVC0X8Elhz+3XFCDoM5yIUQucDzwM1Syk1dtt0A3ABQUlIy78knnxzQufx+P5mZmQNqIxUMpd1ShomYO+lajVngwe2e0a+2Rur9hpFru7J76BkM288555zVfSmX01emz/XJ+18c3+/jzp64c1Dt6I1hoY7rqQaRlPJ+4H6A+fPny7PPPntA51q0aBEDbSMVDLXdgaBOXeO3kDIMWLhdUygu+Acu17h+tTNS7zeMXNuV3UPPcLVddcf1wJGoQaQYPNLTzmecbwMRcwdCZOB29f+NqjeklPjDy2ho+y8IQX76FWR6T1IycIViEJByZHTHpTISGvQaRIrBRQgdj3vmEWt/f+NPaWh7CluGAGhse57CzKsYm/fTI3ZOheLDhK0ioe45EjWIFCOHgLGZ+rankDIYW2fLILX+xynI+CxpnukptE6hGPk46jgVCSkUSWkOLkRKI2G9lCbNoYXKCSkUA0Z1xykU3aKJNAQuJFbceiFcaCItRVYpFEcPzsyqw98JDX8LFUcleemX0l13dV76R4fWGIXiKMWSot/LUKOckCIleFyjmJD/R4TwoYlMNJGJED7K8u/GrRen2jyFYsTTXjuuv8tQo7rjFCkjP+NSctLOpCW4GIQg23cWupaVarMUCsUQopyQIqXoWjZ5GZel2gyF4qjEVsIEhULRmYBZTcRqIcszCU24U22O4ihGSbQVCkWMsFnPykPfodnYikBHCJ05BT9mbJYSYSiODJLUCA36i3JCCsUQsPzg12kxdnRI0iVsqPsZme7x5Ppmp9Y4xVGLkmgrFApajJ34I3sScqIsGWZX8+MpskpxtCMlWFLr9zLUqEhIMeIwLD+VbQuJ2H5K0k4i1zsl1Sb1SNisRyT9qUlCZnW/2vJHKtnc8CC1wXWku0qYmXcdpRmnDI6hiqMMoWrHKRSDTU1wDe9WfRuJU+JHCI0JWRczv+hHR7T6dm1wA1saH6E1UklR2rEck3cdme7RfTo2xzsTm0jCek14KUo/rc82+COVvLH/akw7CNi0mQdoOLiF4wtvYXLO5X1uR/HhQMKIKNsz/C1UfGgIWU0EzBq6m2jRlibvVX8XUwaxZBCbCJYMU9H6BlWBJQCErWYOBdfRFjk4aHbta13IwqpvcCDwHi2RvexueZnX9l9Ni7GvT8d79Bym5HwJvVM5IoEbj5ZLWfbn+mzHpob7Yw6oHUuGWF//J2zZdRZchQKVrKpQ9IW2yCHePXgb9aFtCCFId5Vw2qjbKeoyYF8XXI+UdsLxlgyyu/klqgNr2dH8HJpwY8sIo9Lmc0bpr3Frh1+LTkqbVXV3YclwxzosInaA9fX3cUbpb/vUzvT8r5Htnc7upkcx7CZK0s9icu51ePTsPttSG1xL19luAWxp0RapIssz+HM+KUYuEoGt1HEKRc/Y0uKNyhudCAgbJLRG9vO/ypu5vOwZ0lwFsX27Dux3xh+pZH9gFZY0sKLVuauDq1he8ztOH/Wzw7YvaNUTsVuTbJHUhNb2q63SjHMpzTj3sG2xpIeA7UYiEEi8wkQXEomFV8877HYVRy8jIU9o+FuoOKo5GFhJ2GpxHFAnbCzKW16KW1foOzZpG7pII2A1Y0Unx4u1IQ0q/G9j2qGkx/UFj5ZJ8s5B8A3hg39r03M0mQ1INEAg0QhJNzYexmSchUdX5Y4U8Uicign9XYYa5YQUKaXNPJTggMBxIP7IgU771bO09j4MsgERU5vpIo1R6Sdj2okD/wBIMOXhOyGXlsb4jPPQhSduvS58zMr7wmG32x+ktFlT9yC27HqNAkk2JxWrmWgVyRBYh7EMNao7TgFAxA6xpeklylsX49HSmZ33ccoyTo1TnEkpqQysZk/re7i0NGbkfIR8b9mAzlvgmwVJYg2XSKM47TgAgmYTz+79MmGrBRsLgRefEBSnzeGEwq9S5DueJdU/ZF/b4oS20lyFeLWcAdl4UvEPMA8FqQp8gC7c2NJkVu41lGVeNKB2+4ph+4nYwaTbLCxcmm9I7FCMLNojoeGOckIKLNvg+X0302Tsx4wOwFcHNzI773JOLboRcN7G36z6BRVtyzFlCIHGpqbnOa34Jo7JPfwCpNnu8WS5J9JslCNxFF4CF0J4aIm0ETSbWN/wH9rMFiwkoCEQ2FJSGdzDOZ6pCCE4vvDrVAdXYdkhbExAoAsvC4q/P2DptkvzcWbp7wia9QTNGrI843FrGQNqsz+4tQx0zYOdJNrL6qNMXPHhJBWRTX9RTkjBztZ3aDIqYw4InC6sjY3PMTf3E2S6i6hoWx5zQAASG1OGea/mHiZnnYlP73+00WQc4NmKmzHtEBoaHuG8tZnoNEVMGuv+yfK6f6Ihog5IRM8NJgIPLurD5YxOP55sz3guG/8vtjT+i5rQBnLcE5iVfxX53mkDvj/tpLkK4oQSQ4UmdObkXcWGhkfjuhZ14eWEguuH3B7FyEBKoSIhxcigwr806biJhovq4Eamus9lV+uibvbR2d+2mqnZ/Vd9vVX1G0JWMxIJuAjLzl9HGSeLjp+GVQCSsG2Q7iqMrc1wl3Bi8f/1247eMOwgloyQ1g859WBzbP41aEJnQ8PjGLafdFchJxXexPjMvie7Kj58jIRkVeWEFKS7ChBoiQIBAWnRCEcX3qgwuMv4jRC4ugza94Wg1UxtaGdie31G4NIyyPWMO8zje8fG4tl9t1HR5kix8zyjuWj0dylNm37EztkdQgjm5l/FnLzPY2Oiq2kgFClACDEOeBQYhZO0dr+U8k8DaXP4u0nFEeeY3MuSPNQEbi2N0emOOGBmzkUJCrF2xmWc2KfzNBhVbGt5j0OhXXH6ASnBsHVCtouQrWPYOqbU6KZwQsy+GTkX9um8h4OUksZwJRVta7AxsTGpN/bxVMX38Ufqj9h5e0MIoRyQok9IwI7Wj+vP0gsmcIuUciawALhJCDFrIHaqSEhBvreMc0d9n3cO3QU4IoR0Vz6XjP0tmtABKEmbxbyCa1hV/ygCzRnsl/DRMb/CpXl7bN+SJi9W3km5fwWacCGlRZG3jFzPBOrCewhJV+wHE0M6nW7pGOhCINDj6q+5hY/j8j8zoOv2RxrY2Pw2rWY9ZRnHMiXzpNj1HghuxpImdpcEWRuTDU2vcmrRNQM6t0Jx5BGD3h0npawGqqN/twohtgJjgC2H26ZyQgoApmSfw8TM06gJ78AtfBR4JyeoyuYVXMX07AvZH1iJS/goyzylTyVxltU9Tbl/BaY0IFrN4FBoFxMy5hCRByCuU66TJBxJSHr51NgfU966mPKWRUhsCr2TOaf0FrLcxbF9/WYjGxsXE7CaKcucy6SMYxGi+x9gRdt6nt73c2wsLBlhQ+NbFPkmcNWEO3BpHloihxwBhNTQkGjCsdCSERqMyr7cUoUipTgS7SOnjhNClAHHA8sH0o5yQooYuuahNK3nCdYy3UXMzOnfbKBrG191HFAnLEz2tm0E2mUG7X91RoBwU+ibxqSs0ziv9FaktBIirz3+9TxZ8auoYi/CioZXGJs2nc+X3Y4uEr/iUtr8t/J3RDoJLSIySE1oN2saX2Fu7gUsqXmeHI7DsJ3jNWy8molb8zEm7Zh+Xb9CkSoOs2xPoRBiVafP90sp7++8gxAiE3gW+LaUsmUAJionpDjyGN2WzZHo6NG8nuRoaJi248B04YIuTsWWFs/sv5NIJyVdxA5RGdjG+saFnJCfOG5UE96LaYcT1pvSYFPzQiratlMfriKH42h3jDYapnSRpWdwTM75vVzx8GCXfx1rGt7EsMPMyT2DY3LOQI92Nw4VjcYhVje8TcBqZkrm8czIPjHW5ak4sgyggGmdlHJ+dxuFEG4cB/QvKeVzh2tfO8oJKY44kzLnsa3lvQT1XYF3LGN809jS8g6WbTqZQF1+Mz49kzxP9wmZ1cFdWEmmMYjIMOub3k7qhHThSloqCBzJ+Y7WFVgJjlEAaVwz8R48enq39gwX/nfwUZbXvxxzznvbNrGucSFXl90+ZE5gW8tKntp3F7a0sTBZ37SEUt9Erpv4c1yaElcMBYM9vbdw+ugfArZKKf8wGG0qdZziiHNOyZdI0zNjUm4dF27h4+LSb3FG8XWE7Sz8lgcbEVPEadF9Pjbm1h4rHjjjPslldBrJH7YFnnFkuPIT1ruFlzm5F3Q7n5EmXEmPG25Y0mRZ/Yvx0aEMsbdtM6sa3hoSG0w7wjP77yYijZhDN+wQVcHdrG18Z0hs+LDjTO8t+r30wmnANcC5Qoh10aV//fNdSFkkdCT05iOZlkgj79a+yC7/JvI8RZxZ9HEmZAx9Pkp/MewwW1tWEzD9TMmaTZE3MWrJcRdzw5QHWNv4KgcCWyn0jueE/EvJcRfz0oEHCNsmoBG0PLiEjUtIStOm8pnxPyDbXdTj+Ut9k/Bo6Qldfm7h5fj8C5IeI4Tgk+Nu44mKHzgKOGkBgqlZCzgh72JW1L9Obbgi/hg0pmR120MxrDDsIAIduszmamPyctUDuLV0js8784jacCC4k2QvB06EuogpWcejCxfZbjUFxZFksIUJUsr3SBy8HRCp7I5r15uvEUJkAauFEG9JKQ9b6jdSaTbq+dPO7xKygtiYVIX2sqN1HZ8c+3WOyzs91eZ1y/5AOQ/s+iUSG1vaSODE/HO4fMyXE6KXND2LUws/m9DG6oaFmLHq0AJT6pgSDgSrqQ5VsbLhPfI9xczOORG3lpinJITGZ8f/mMf3/sQRJlgmhtSJCC+vVD1NZeAA55Z8Al+XLrRi30S+MfUxyv0raDMbGZc+m2LfRAA+NuZmHtt7GyL6W3MJDx7Nx/kl1w78pg0BQnRI6DsjpZOA+1zl3zkm5yQ8R7DwqUt4uk1Ergzs5vfbvgVAsW8s10z4Pwq8o46YLR9WnDGh4d/ZlTILpZTVUso10b9bgXa9+YeOt2ueJmQFOg3QSyLS4IWqB7Fk9xO5pRJbWvxzzx2E7ABhO0REGpjSYHXjIra0rOq9AZyE0K6quXYMO8Qje//A6wef4pnK+/nN1m9QHz5Ec6SRJbWv8fahF6gO7gdgTPpUvjP9n3y09Gukucdh4iZsh2mM1PJu3avcu/O2pFM9uDQPM7JPZ17+ZTEH5LQ3ja9NuZcMVy7Tsk7krOLPcdPU+8jx9ByVDRe8WjpaNz9tS+poQmOP/8i+65WmTcLXTZHXkB3BlM5SHdzLX8t/0v1UHIoBoaZy6CODpTcfqexoXZ+QFAlOTkqjUUOhtzQFVvXMvkA5kSQKM8MOs7z+fxyT03sVBSEEEzJmsbdtC11f2yVarIstbIcw7DD37/otjZH6aP6DzRsHn+W0wgv4+Jhr8Ohp5HnH0WjUd4qsovcwUsvmlpUcm3tqn68vx1NElquAyyb8pM/HDBcEgsvHfId/7/tV3PqI1JDt0V2SqHIw0YTG1WU/5p97footLUecIE0sGT9BuURi2GG2ta45ovZ8GDnSeUKDhehuEHbIDHD05ouBXyeT+wkhbgBuACgpKZn35JNPDuh8fr+fzMzMAbUx2NSGD2AkeaALBKPSJgDQ2tpCyB1AFzpZ7hy8KZ5DJmyHqA8fTKoy82ppMcfZ2/02pUFt+EBUDNBeKVv2pXwI4IzVFHlH4dF8tJktNEXqSTYWkeHKJtddmNhAJ2xsIraBLnRcwj0svytdicgIOlqc4s3v92N5w/jNZuLvhXNPNaFR6isbIgtlNMq3CVtBApY/yT6CXHcBMqQN+/vdHYPxXTnnnHNW9ySN7i9FswrlFY9e0u/jHjjx0UG1ozdSGgn1RW8eTZK6H2D+/Pny7LPPHtA5Fy1axEDbGGw2NH3A0/vvjVMz6cLFlMy5nDzu09yx9YdMD85jebGjbPJoHj42+nOcVfyRVJlMxDb4xeavEO4y2ZpHeLl87FeYn3820Lf73RJpYHn9G1QHdzM6bTLv1b2N34rPf7Mlsbf4zggECwrO4zPjvsLm5pU8ue9pwl1ECi7h4aJRn+PM4uR2WLbFveV3sDPaRSUQjPKNYQEfGXbfFUuaGLbBuoaVPFf1GFJKLGkxNXMm1038BumuDBYtWsSmMSvYG9iO1qmDxZQahq3j1bOYntXCJaWfYHTa2CGzfUPTUp7a/9ekIpIbp9zO7hUHht397ivD8bkC9PllLpWkUh036Hrzkcrc3FOpDVfxTs1zaOgEbQvIJmJn8vT+x/CbrXGyYcM2eLHqSRYUnIVXT01E5NY8fG78zTxRcXcsD8Sj+ZiQPo3j887oV1vZ7nwuGHVl7HPAMvig/g3MTvk/jkggsYq381kStAK4RAZuzYthh+P204XOvPyzuj3/A7v/EHNA7W1WhyqpDR3s13UMFkY0OdfTqcvMkibPVT7J+3ULMaWJ7QjaYyM/O/xbeGj3n7h52o8AKE0bx77AzmicKjFtgSFdgCBgBVjXtJItLeu5ZdrtjE0fPyTXdUzOieQfKqYuXB3rMnULDxMzZzI+fSq7OdBLC4r+0C7RHu6kMhJq15tvFEKsi677kZTy1RTalDLOK/kUpxZczN92302TfzeGbGNN08rowzexy0tD50BwH5MyB2/Stv5yTM6JfHfG3axuWIzfbGZ69vFMzzoOrYeabX3hwlGfYod/A41GLWE7hEfz4sJN0DbixnvAibwMS3Lr+m/gEi4saZHp8iGJIBDkugu5csK3yHAlnwsoZAXZ3LIu6TbDDtMSaSbbPbDpwftKbbiGR/fezy7/TgCmZc3kC2XXk+8p4Ml9j7Ci4X0inYQcnTswLWmyu20HDUYdAGcWXcrqxncdhyw7HFDHsZKwHeaFqv9w05Tv9dvWlkgzutDJcPW9C0oXLr4+5Vcsqvkva5vewyVcnJh/HmcUDSjNRNEDI0EdlzIndCT05iOdfcEK9rbtwYh70CQfs3MetllDZVq35HmKOH/Upwa1TZ+ezv9Nu5OtLWvZH9hFXbiZzS07CFl1uDQTXehIaaMLF5Myj2FF43IiMkIk6qCaIzqTMmfx5YlfJ8ed32Oya6PR87QMQattSJyQYYe5c9vPnag3+n++o3Urd277BT+e+UuWN7yX4IBBYCNjKbku4aIl0gxAkbeUGybdxrOVD0RVhMnvwZ628n7ZWdG2l3/s+Tu14RokkokZk/nKpK+S7+nbjLM+PY2LSq/kotIre99ZMSAGULZnSBn+bvJDxMamtYSTCBScbqgONDRK08ZS7Bt+qrnBQhMax+TMQ5LBBw2rqDVqCdoSv+khbOmcUngh3572Sw6FmvGbJmFbJ2zrmLbAlBZ72nYjhN6jAwLI8xTE8oESEIJCb8mAr0VKydaWrTxX+RxvHnyTlkgLUkps2RHhrmpYntCNaGMTtAKsbFyaUPOtvavFsHQithb9bFHq68hyKMuYxi3Tf88vZ/8DdzdzEOX0I1m0NdLK/9v+W6pDVZjSxJIWu/3l3Lnt13HXolD0h2Eh0VY4pOkZ6OhYXeTaLuFCIPBpac6DJm0sN06+JUVWDh0RO8LL1S/GKQclgqAN1cEmPFoGewNVUcGC40gsNKSU+IROm9lGjju3x3P49DROKTibD+oTS8nkuPO6LfgZsSOsaljNrrbdlHhLOLXwFDJciTXlLGnx551/ZnvrdsJ2GLdw81TlUwjpwpARxqWN5Zqyq6gNH0r6AhKxDUJWKE6FKCWEbVes8rglJYZ0cU7xBUnHCNNc6ZxScBZL65fEdedpaBR4RlMbrqPI27NyEGBp/XtYXZyNjU3AbGNzy0bm5BzbaxuKoWUkCBNUJDSMOLng1KTFJXWhMzptHF+bcis/mPkbvjfjl2T38nA9Gmg0Grvdti9QwWsHX4NODsjBmR1SoFPi64hiWiKtNEcSK84btkGhdxIebQwB00vE0ojYaUiK8UcCLDy0OOEt32/6+dHGn/LPvY/y1qG3earyGb67/vtUBhIH1pfWL2Vb67aYg4nICJa0okpIyf5gJXdt/yPpelZS2b1b8zA+vYzZ2SdjWF5CpgvD1rtMfeFEyksbus+1+dTYqzkx/xRcwu1M5S4haAlWNW7iRxt/wrrG9d0e205N6FCcE2vHkhb14bpej1cMLe15Qv1dhhoVCQ0jCr3FfGHCV3hs34Ox4psC+OqU71C9+lBKRQiDSaPRxCvVb7C5ZRsFnjwuKb2ImdmJ15btzu62m6fIW8yetj3djJkJzi66EF24OBSq4Z7yB9gXcCaiG+Ur5qYp1zM+fSyGbfCzTb/hULgmqkjTMKQXDQ3baiVsGzyx7z9sb93J16Z8Jdb6s5XP02DUY0arWRi2gYHBA7sf4uezfxpnyft178fUbt0RsSPsaN1DrjuPunBNp0hYkOnK5q2D77K5ZSthWwAudKyEauMA9UY9e9r2JD2HS3Nx9YTrKfZM4OkDz2LYEaKSBixp8bfdD3DP8Xfj0rrAe1WBAAAgAElEQVR/JEzJmsryhg8SIjYhBJmuHPa0VTAubUyPbSiGFiVMUPSbEwtOYU7u8exo3YIuXEzLmolbc1PNoVSbNig0GI38cOMvCFpBLGmxL1DJ5pbtfLHsKs4siq9o4NN9nF54Ju/Xvxv3IHfypC7ng/qlVLRVYHdRD+pC58ziczBtk59v+R0tkY7B/spgFb/ccid3H3cHy+qXd3JAHXRuL2wbrGxYzeXBSylNc+qbrWxYHXNAndkfrCRgBkhP0i3XExLJgVAV35j8bX6x9XaktGKzulYG/VQFN8XJ1XtoiFUNayiie5HAysY1GLZJV6GClJLdbXuYljW122Pn5Z3Ey1UvUG/Ux6bPcAk3ttT5S/k/0dDRhcYNk67lpILj+3LpiiNJiiKb/jL83eSHEJ/uY27uCRyTMxf3UTbvygsHXiFoBuNq4hm2wWMVT2LaiQ/a43JPwiOKCJhewpabLD2HL5ddz4zsmVw86uKE++MWbo7LPY58Tz5rmtYTtsIJ0ZIpLT6oX87KhrW9RingiCR2+nfFPus9SNC7ytPDtqS3oiSOlDyfNw8tJmDp+C0fbZaPsO3GklaCA5KQ0KaU7et7PlmyIrBOm7Jb8ULHsW5+OPN2zi46l1x3HgWeQiQ+miI2hh0hZIdoswLcu+shDgSre75oxRFH4owJ9XcZapQTUgwpG5q3JAgvwKkFdzBUE7fu/doV/G7bvVSH6p25TmwPzRGdcelOsdHStFJumXYLY9PGIhC4hZszi87kxkk3AlAfbkgaQRi2QW2onmx333JcBII8T8cY3OmFpyU8sDU0pmVOxddJGBCywpS3VmBJZ56kzoth68RmbZWSDU27ebV6CYbVu8qs/e22c3vgJH6ekHdcj8eeU3wm3i7TowOk6+lMyOg9aTXDlcFnx1/FncfezbVlXyVkiYQOUdM2eevg4l7bUhx51JiQQtGFHHc2NeHahPWWtMjq5BQsafGPvf8h3ClSsbAIWkGernyZm6ZcB8DUrKn8cvYvMW0TTWhxkcikzDJ04UroOvNpXqZkTSTXfSyrG9f1GA0JBBmudI7Jnhlb9/Exl7GjdScVgX3Y0o4mbWZww+Qvxx0bsIIQnRbckhJN2DhqNueHHjT1Tm+eZjTpVMO2JEKALmwQyTJ8NCzbRrRvE+ARHk4pWMDkzMlUUtnt9czPm8eWwq28W/s+Qgg0NHSh851p3+x3knFzpCWpvN3Gpt5o6FdbisFnpBQwVU5IccSQUtJitvHllT+m0Wim2JvP6LQCdKHHdce5hItZ2TPIcXdUNagLNxBJUt7fRrKpeVvC+mSD4dMypzApYwLl/j2xRFaXcFHoLeSE3GNxaS4+O+4TPLnvWVyajpQSj+4F6VQT0IRgfPo4vjn1a3EPaI/m4Uczv89OfzkVbfso8hYyJ3d2gpw7151NuiuN5kgEicCSevS+ODUwLDTaC7Z2IJDRGWZNqeEWkhJfPk2RRjShEbIcUYBhuxGArtnoaFxZ9nnOKTqj17woIQTXll3DR0ZdyLaWbWS6sjg2d85hdftOzZqUNNL0ah6OzT2m3+0pBh/lhBQpw7QtDgRryHZnkOdJXrKmMwEzyOKaVewLVjM5cxxnFM7Dqw+s3P9r1UuoCzfSYDQBcChcz6FwPRrg1Z2xFV3oTMuawk1Tro87NsOVnpCT0k5rJEDQCpHWS908IQS3zvg2r1S9zuK6D7ClzSkFJ3H5mEtiTuvCUedzeuGplPt3k+5KZ3LGRCSSQ6EaNi/bzLVzvtBt28XeEl6vXs7DDW/g1txcWHIqnx53YeyBrgmNL5ZdyV93/TMh2nIcUofEur02Rsdk5c42U2rcNPVGCr25PLXvBRbXLidsOzPBSsC2NUwEVYH6Xh1QZ0b5ShjlG1gibr4njwtKzubtmiWxiNUt3BR48jmjcMGA2lYMnJFSMUE5oaOQhYdWcP+uZ7CljSktZuVM5vszvkiWO/kkY9XBWm5dfxdhO0LYNvBpXp6oeJm7jruVfM/hlayxpc2T+1/hLGYnbkMnaGl4NRefnvAxPjb6/IR9Ml0ZnJA3mxUN8XXdpARD2jxX+RZXTbgs4bjd/kperFpEbaiRE/JmclHpaVwx9jKuGJu4bzvprnTm5nbYKRCUpo1iu0iMuNoJWmH+b92dNBktWFE13fMH/seO1j38bPY3YvudXDCPPE8uLxx4jR3+PbRE/Jiya24TdHZE8dUxBOubtvGJsR9hUuZkFteuJlktwa4KwaHi6gmfZmrWJN48+A4BK8jJ+fO4qPQ8vHriuJNi6FHJqoohZ2vLbv5a/iRtVpCgHSYiTTY3l/PrLQ90e8y95U/QagZib7MhO0yj0co/diedXaNPhG0jOibSHYKwbbGiflO3e1w57gqk1OIG4C0piEjJktqVCfu/X7uWW9f/gXcOrWBD8w6e2PcqN6/5LS2RtsO+ju5YdGgFfjMQc0AAhh1hS8tudvvjx2SmZU3m2rLP0xi2CFk6MunbaXJVmylt3q1dgy1t5uXNSZo35dbcnFowL2G9JS1W1G/m1eoP2OXvfpxoIAghWFAwn58e8z3umPtTrhh7Sa8RqmKIkEqYoEgBz1W+HU1E7MCUFjv9+zgYrGNUWnx5FktabG4uT5Ax29isaNh42HZ4NU+fHkZaD11IaS4fUrqJyAiaiO+m6npcs+Hn99seIxwdoxBA2IrQJFt4vvJtrp34scO8kngsabOmYRtvHVpB0DLQupgvgD1tlUzKjJ+nZ13TVmdcSWqAjZTEJZwKNAQSO1YXu4OKthpeqXqPy8acyZcmfZZ/7nkKS9pIaePSXFw06iymZJXFHXMwWM/31v+ZNisYc1zH507nx7O+hEtLXopIcXShhAmKlFAbbkz6Tu0SOg1GS4ITAuGM
Categories : Practice