繁体   English   中英

Matplotlib:figure.add_axes 从 x,y 转换为相对坐标

[英]Matplotlib: figure.add_axes convert from x,y to relative coordinates

我正在制作一个自组织地图,我想将其显示为六边形点阵,其中蜘蛛图表示相应单元格中的权重向量/神经元,并且能够通过以下方式创建六边形网格:

def hex_plot(ws,a=1):
    """
     plots a m (rows) x n (cols) hexagonal grid with offset rows where a is 
     the hexagon's side length and m and n are determined by the first two 
     dimensions of the weight vectors ws
    """
    m,n,_ = ws.shape
    offsety = .75 * 2*a
    offsetx = numpy.sqrt(3) * a
    oddrow = numpy.sqrt(3)/2 * a
    x,y = 0,0

    fig,ax = plt.subplots(figsize=(7.5,7.5))
    ax.set_aspect('equal')
    ax.set_zorder(1)

    cs = {}
    for i in range(m):
        for j in range(n):
            offsetr = oddrow if i % 2 != 0 else 0
            cp = (j*offsetx+offsetr,-i*offsety)
            cs[(i,j)] = cp
            hexg = RegularPolygon(cp,numVertices=6,radius=a,facecolor='white',edgecolor='k')
            ax.add_patch(hexg)
            ax.text(cp[0], cp[1], "{},{}\n{:.2f},{:.2f}".format(i,j,cp[0],cp[1]), ha='center', va='center', size=10)
    xy = [cs[(i,j)] for i in range(m) for j in range(n)]    
    ax.scatter([x for x,_ in xy],[y for _,y in xy],c='white',alpha=0.5)
    ax.set_xticks([])
    ax.set_yticks([])
    plt.show()

这给了我以下内容:
5x4 空白六边形网格

有了这个,我正在尝试放置表示每个权重向量的神经元5x4 训练 SOM的蜘蛛图,以便 0,0(左上角)处的蜘蛛图位于 0,0(左上角)处的六边形单元格内。 我尝试使用子图,但在具有极坐标投影的蜘蛛图中出现了困难,而网格则没有。 我的第二次尝试涉及使用“add_axes”。 通过在上面代码中的 plt.show() 之前添加以下内容:

w = ws[0][0] # current weight vector
a = numpy.linspace(0,2*numpy.pi,len(w),endpoint=False)
a = numpy.concatenate((a,[a[0]]))
w = numpy.concatenate((w,[w[0]]))

ax1 = fig.add_axes([0.0,0.0,0.1,0.1],polar=True,zorder=2)

ax1.set_thetagrids([])    
ax1.fill(a,w,alpha=1.0)
ax1.set_yticklabels([])
ax1.set_rticks([])

我可以在左下方画布上放置一个蜘蛛图:蜘蛛图 over hex ,但是由于 add_axes 中指定的矩形是相对于图形的坐标,我无法确定原始轴中的坐标 0,0(六边形 0 ,0) 将映射到相对坐标。 我查看了转换,但没有帮助。

有没有人遇到过这个问题并提出解决方案? 谢谢

我在这里看到两个选项:

在单个轴上绘制所有形状

由于看起来不需要特殊的极轴,因此您可以在六边形的相应位置在相同的轴上绘制所有填充。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon


def hex_plot(ws,a=1):
    """
     plots a m (rows) x n (cols) hexagonal grid with offset rows where a is 
     the hexagon's side length and m and n are determined by the first two 
     dimensions of the weight vectors ws
    """
    m,n,l = ws.shape
    offsety = .75 * 2*a
    offsetx = np.sqrt(3) * a
    oddrow = np.sqrt(3)/2 * a
    theta = np.linspace(0, 2*np.pi, l+1)

    fig,ax = plt.subplots(figsize=(7.5,7.5))
    ax.set_aspect('equal')
    ax.set_zorder(1)

    cs = {}
    for i in range(m):
        for j in range(n):
            offsetr = oddrow if i % 2 != 0 else 0
            cp = (j*offsetx+offsetr,-i*offsety)
            cs[(i,j)] = cp
            hexg = RegularPolygon(cp,numVertices=6,radius=a,
                                  facecolor='white',edgecolor='k')
            ax.add_patch(hexg)
            ax.text(cp[0], cp[1], "{},{}\n{:.2f},{:.2f}".format(i,j,cp[0],cp[1]), 
                    ha='center', va='center', size=10)

            r = ws[i,j,:]
            r = np.concatenate((r, [r[0]]))
            x,y = (np.c_[r*np.sin(theta), r*np.cos(theta)] + cp).T
            ax.fill(x,y, color="C0")


    ax.autoscale()
    ax.set_xticks([])
    ax.set_yticks([])
    plt.show()


hex_plot(np.random.rand(5,4,6),a=1)

在此处输入图片说明

使用inset_axes

如果您确实需要轴,例如显示网格,您可以将inset_axes放置在相应的位置。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from matplotlib.projections import get_projection_class

def hex_plot(ws,a=1):
    """
     plots a m (rows) x n (cols) hexagonal grid with offset rows where a is 
     the hexagon's side length and m and n are determined by the first two 
     dimensions of the weight vectors ws
    """
    m,n,l = ws.shape
    offsety = .75 * 2*a
    offsetx = np.sqrt(3) * a
    oddrow = np.sqrt(3)/2 * a
    theta = np.linspace(0, 2*np.pi, l+1)


    fig,ax = plt.subplots(figsize=(7.5,7.5))
    ax.set_aspect('equal')
    ax.set_zorder(1)

    cs = {}
    axcs = {}
    for i in range(m):
        for j in range(n):
            offsetr = oddrow if i % 2 != 0 else 0
            cp = (j*offsetx+offsetr,-i*offsety)
            cs[(i,j)] = cp
            hexg = RegularPolygon(cp,numVertices=6,radius=a,
                                  facecolor='white',edgecolor='k')
            ax.add_patch(hexg)
            ax.text(cp[0], cp[1], "{},{}\n{:.2f},{:.2f}".format(i,j,cp[0],cp[1]), 
                    ha='center', va='center', size=10)

            axins=inset_axes(ax, width="100%", height="100%", 
                             bbox_to_anchor=(cp[0]-offsetx/2, cp[1]-offsety/2, offsetx, offsety),
                             bbox_transform=ax.transData, borderpad=0, 
                             axes_class=get_projection_class("polar"),
                             )
            axins.set_zorder(4)
            axcs[(i,j)] = axins

            r = ws[i,j,:]
            r = np.concatenate((r, [r[0]]))
            axins.fill(theta,r)

            axins.set_yticklabels([])
            axins.set_xticklabels([])


    ax.autoscale()
    ax.set_xticks([])
    ax.set_yticks([])
    plt.show()


hex_plot(np.random.rand(5,4,6),a=1)

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM