| 205 | |
| 206 | |
| 207 | def annotate1(X, index_word_map, eps=0.1): |
| 208 | N, D = X.shape |
| 209 | placed = np.empty((N, D)) |
| 210 | for i in range(N): |
| 211 | x, y = X[i] |
| 212 | |
| 213 | # if x, y is too close to something already plotted, move it |
| 214 | close = [] |
| 215 | |
| 216 | x, y = X[i] |
| 217 | for retry in range(3): |
| 218 | for j in range(i): |
| 219 | diff = np.array([x, y]) - placed[j] |
| 220 | |
| 221 | # if something is close, append it to the close list |
| 222 | if diff.dot(diff) < eps: |
| 223 | close.append(placed[j]) |
| 224 | |
| 225 | if close: |
| 226 | # then the close list is not empty |
| 227 | x += (np.random.randn() + 0.5) * (1 if np.random.rand() < 0.5 else -1) |
| 228 | y += (np.random.randn() + 0.5) * (1 if np.random.rand() < 0.5 else -1) |
| 229 | close = [] # so we can start again with an empty list |
| 230 | else: |
| 231 | # nothing close, let's break |
| 232 | break |
| 233 | |
| 234 | placed[i] = (x, y) |
| 235 | |
| 236 | plt.annotate( |
| 237 | s=index_word_map[i], |
| 238 | xy=(X[i,0], X[i,1]), |
| 239 | xytext=(x, y), |
| 240 | arrowprops={ |
| 241 | 'arrowstyle' : '->', |
| 242 | 'color' : 'black', |
| 243 | } |
| 244 | ) |
| 245 | |
| 246 | print("vocab size:", current_index) |
| 247 | |