【发布时间】:2021-02-04 22:00:09
【问题描述】:
我一直在使用出色的 minisom 包,并希望以交互方式绘制反映自组织地图训练过程结果的六边形地图。已经有一个代码示例使用 matplotlib 静态执行此操作,但要以交互方式执行此操作,我想使用散景。这就是我苦苦挣扎的地方。
这是生成一个简化的 matplotlib 示例的代码,该示例已包含在包 page 上:
from minisom import MiniSom
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon
from matplotlib import cm
from bokeh.plotting import figure
from bokeh.io import save, show, output_file, output_notebook
output_notebook()
data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/00236/seeds_dataset.txt',
names=['area', 'perimeter', 'compactness', 'length_kernel', 'width_kernel',
'asymmetry_coefficient', 'length_kernel_groove', 'target'], sep='\t+')
t = data['target'].values
data = data[data.columns[:-1]]
# data normalisation
data = (data - np.mean(data, axis=0)) / np.std(data, axis=0)
data = data.values
# initialisation and training
som = MiniSom(15, 15, data.shape[1], sigma=1.5, learning_rate=.7, activation_distance='euclidean',
topology='hexagonal', neighborhood_function='gaussian', random_seed=10)
som.train(data, 1000, verbose=True)
# plot hexagonal topology
f = plt.figure(figsize=(10,10))
ax = f.add_subplot(111)
ax.set_aspect('equal')
xx, yy = som.get_euclidean_coordinates()
umatrix = som.distance_map()
weights = som.get_weights()
for i in range(weights.shape[0]):
for j in range(weights.shape[1]):
wy = yy[(i, j)]*2/np.sqrt(3)*3/4
hex = RegularPolygon((xx[(i, j)], wy), numVertices=6, radius=.95/np.sqrt(3),
facecolor=cm.Blues(umatrix[i, j]), alpha=.4, edgecolor='gray')
ax.add_patch(hex)
for x in data:
w = som.winner(x)
# place a marker on the winning position for the sample xx
wx, wy = som.convert_map_to_euclidean(w)
wy = wy * 2 / np.sqrt(3) * 3 / 4
plt.plot(wx, wy, markerfacecolor='None',
markeredgecolor='black', markersize=12, markeredgewidth=2)
plt.show()
matplotlib hexagonal topology plot
我尝试将代码转换为散景,但生成的十六进制图(对我来说,是原始的)看起来需要垂直翻转到点上并矫正歪斜。
tile_centres_column = []
tile_centres_row = []
colours = []
for i in range(weights.shape[0]):
for j in range(weights.shape[1]):
wy = yy[(i, j)] * 2 / np.sqrt(3) * 3 / 4
tile_centres_column.append(xx[(i, j)])
tile_centres_row.append(wy)
colours.append(cm.Blues(umatrix[i, j]))
weight_x = []
weight_y = []
for x in data:
w = som.winner(x)
wx, wy = som.convert_map_to_euclidean(xy=w)
wy = wy * 2 / np.sqrt(3) * 3/4
weight_x.append(wx)
weight_y.append(wy)
# plot hexagonal topology
plot = figure(plot_width=800, plot_height=800,
match_aspect=True)
plot.hex_tile(q=tile_centres_column, r=tile_centres_row,
size=.95 / np.sqrt(3),
color=colours,
fill_alpha=.4,
line_color='black')
plot.dot(x=weight_x, y=weight_y,
fill_color='black',
size=12)
show(plot)
如何将其转换为散景图?
【问题讨论】:
标签: python-3.x matplotlib plot bokeh hexagonal-tiles