python - Matplotlib RegularPolygon collection location on the canvas -


i trying plot feature map (som) using python. keep simple, imagine 2d plot each unit represented hexagon.

as shown on topic: hexagonal self-organizing map in python hexagons located side-by-side formated grid.

i manage write following piece of code , works set number of polygons , few shapes (6 x 6 or 10 x 4 hexagons example). 1 important feature of method support grid shape 3 x 3.

def plot_map(grid,              d_matrix,              w=10,              title='som hit map'):     """     plot hexagon map each neuron represented hexagon. hexagon     color given distance between neurons (d-matrix) scaled     hexagons appear on top of background image whether hits array     provided. scaled according number of hits on each     neuron.      args:     - grid: grid dictionary (keys: centers, x, y ),     - d_matrix: array contaning distances between each neuron     - w: width of map in inches     - title: map title      returns matplotlib subaxis instance     """     n_centers = grid['centers']     x, y = grid['x'], grid['y']     fig = plt.figure(figsize=(1.05 * w,  0.85 * y * w / x), dpi=100)     ax = fig.add_subplot(111)     ax.axis('equal')     # discover difference between centers     collection_bg = regularpolycollection(         numsides=6,  # hexagon         rotation=0,         sizes=(y * (1.3 * 2 * math.pi * w) ** 2 / x,),         edgecolors = (0, 0, 0, 1),         array= d_matrix,         cmap = cm.gray,         offsets = n_centers,         transoffset = ax.transdata,     )     ax.add_collection(collection_bg, autolim=true)     ax.axis('off')     ax.autoscale_view()     ax.set_title(title)     divider = make_axes_locatable(ax)     cax = divider.append_axes("right", size="5%", pad=0.05)     plt.colorbar(collection_bg, cax=cax)      return ax 

i've tried make automatically understands grid shape. didn't work (and i'm not sure why). appear undesired space between hexagons

6x6

3 x 3

11 x 3

summarising: generate 3x3 or 6x6 or 10x4 (and on) grid using hexagons no spaces in between given points , setting plot width.

as asked, here data hexagons location. can see, same pattern

3x3

  {'centers': array([[ 1.5       ,  0.8660254 ],    [ 2.5       ,  0.8660254 ],    [ 3.5       ,  0.8660254 ],    [ 1.        ,  1.73205081],    [ 2.        ,  1.73205081],    [ 3.        ,  1.73205081],    [ 1.5       ,  2.59807621],    [ 2.5       ,  2.59807621],    [ 3.5       ,  2.59807621]]),   'x': array([ 3.]),   'y': array([ 3.])} 

6x6

{'centers': array([[ 1.5       ,  0.8660254 ],    [ 2.5       ,  0.8660254 ],    [ 3.5       ,  0.8660254 ],    [ 4.5       ,  0.8660254 ],    [ 5.5       ,  0.8660254 ],    [ 6.5       ,  0.8660254 ],    [ 1.        ,  1.73205081],    [ 2.        ,  1.73205081],    [ 3.        ,  1.73205081],    [ 4.        ,  1.73205081],    [ 5.        ,  1.73205081],    [ 6.        ,  1.73205081],    [ 1.5       ,  2.59807621],    [ 2.5       ,  2.59807621],    [ 3.5       ,  2.59807621],    [ 4.5       ,  2.59807621],    [ 5.5       ,  2.59807621],    [ 6.5       ,  2.59807621],    [ 1.        ,  3.46410162],    [ 2.        ,  3.46410162],    [ 3.        ,  3.46410162],    [ 4.        ,  3.46410162],    [ 5.        ,  3.46410162],    [ 6.        ,  3.46410162],    [ 1.5       ,  4.33012702],    [ 2.5       ,  4.33012702],    [ 3.5       ,  4.33012702],    [ 4.5       ,  4.33012702],    [ 5.5       ,  4.33012702],    [ 6.5       ,  4.33012702],    [ 1.        ,  5.19615242],    [ 2.        ,  5.19615242],    [ 3.        ,  5.19615242],    [ 4.        ,  5.19615242],    [ 5.        ,  5.19615242],    [ 6.        ,  5.19615242]]), 'x': array([ 6.]), 'y': array([ 6.])} 

11x4

  {'centers': array([[  1.5       ,   0.8660254 ],    [  2.5       ,   0.8660254 ],    [  3.5       ,   0.8660254 ],    [  4.5       ,   0.8660254 ],    [  5.5       ,   0.8660254 ],    [  6.5       ,   0.8660254 ],    [  7.5       ,   0.8660254 ],    [  8.5       ,   0.8660254 ],    [  9.5       ,   0.8660254 ],    [ 10.5       ,   0.8660254 ],    [ 11.5       ,   0.8660254 ],    [  1.        ,   1.73205081],    [  2.        ,   1.73205081],    [  3.        ,   1.73205081],    [  4.        ,   1.73205081],    [  5.        ,   1.73205081],    [  6.        ,   1.73205081],    [  7.        ,   1.73205081],    [  8.        ,   1.73205081],    [  9.        ,   1.73205081],    [ 10.        ,   1.73205081],    [ 11.        ,   1.73205081],    [  1.5       ,   2.59807621],    [  2.5       ,   2.59807621],    [  3.5       ,   2.59807621],    [  4.5       ,   2.59807621],    [  5.5       ,   2.59807621],    [  6.5       ,   2.59807621],    [  7.5       ,   2.59807621],    [  8.5       ,   2.59807621],    [  9.5       ,   2.59807621],    [ 10.5       ,   2.59807621],    [ 11.5       ,   2.59807621],    [  1.        ,   3.46410162],    [  2.        ,   3.46410162],    [  3.        ,   3.46410162],    [  4.        ,   3.46410162],    [  5.        ,   3.46410162],    [  6.        ,   3.46410162],    [  7.        ,   3.46410162],    [  8.        ,   3.46410162],    [  9.        ,   3.46410162],    [ 10.        ,   3.46410162],    [ 11.        ,   3.46410162]]),   'x': array([ 11.]),   'y': array([ 4.])} 

i've manage find workaround calculating figure size of inches according given dpi. after, compute pixel distance between 2 adjacent points (by plotting using hidden scatter plot). way calculate hexagon apothem , estimate correctly size of hexagon's inner circle (as matplotlib expects).

no gaps in end!

import matplotlib.pyplot plt matplotlib import colors, cm matplotlib.collections import regularpolycollection mpl_toolkits.axes_grid1 import make_axes_locatable import math import numpy np  def plot_map(grid,              d_matrix,              w=1080,             dpi=72.,             title='som hit map'): """ plot hexagon map each neuron represented hexagon. hexagon color given distance between neurons (d-matrix)  args: - grid: grid dictionary (keys: centers, x, y ), - d_matrix: array contaning distances between each neuron - w: width of map in inches - title: map title  returns matplotlib subaxis instance """ n_centers = grid['centers'] x, y = grid['x'], grid['y'] # size of figure in inches xinch = (x * w / y) / dpi yinch = (y * w / x) / dpi fig = plt.figure(figsize=(xinch, yinch), dpi=dpi) ax = fig.add_subplot(111, aspect='equal') # pixel size between data points xpoints = n_centers[:, 0] ypoints = n_centers[:, 1] ax.scatter(xpoints, ypoints, s=0.0, marker='s') ax.axis([min(xpoints)-1., max(xpoints)+1.,          min(ypoints)-1., max(ypoints)+1.]) xy_pixels = ax.transdata.transform(np.vstack([xpoints, ypoints]).t) xpix, ypix = xy_pixels.t  # in matplotlib, 0,0 lower left corner, whereas it's # upper right image software, we'll flip y-coords width, height = fig.canvas.get_width_height() ypix = height - ypix  # discover radius , hexagon apothem = .9 * (xpix[1] - xpix[0]) / math.sqrt(3) area_inner_circle = math.pi * (apothem ** 2) collection_bg = regularpolycollection(     numsides=6,  # hexagon     rotation=0,     sizes=(area_inner_circle,),     edgecolors = (0, 0, 0, 1),     array= d_matrix,     cmap = cm.gray,     offsets = n_centers,     transoffset = ax.transdata, ) ax.add_collection(collection_bg, autolim=true)  ax.axis('off') ax.autoscale_view() ax.set_title(title) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="10%", pad=0.05) plt.colorbar(collection_bg, cax=cax)  return ax 

Comments

Popular posts from this blog

how to proxy from https to http with lighttpd -

android - Automated my builds -

python - Flask migration error -