代码之家  ›  专栏  ›  技术社区  ›  Chris McCarthy

如何在matplotlib雷达图中添加轮盘赌背景图像

  •  1
  • Chris McCarthy  · 技术社区  · 6 年前

    我有一个程序,可以在雷达图上绘制轮盘赌数字的命中频率。我想要一张车轮外圈/雷达图外部边缘的图像。我曾尝试在线寻源代码,但发现错误:

        raise TypeError("Image data cannot be converted to float")
    TypeError: Image data cannot be converted to float
    

    我使用的代码示例(见下文)生成以下曲线图:

    enter image description here

    from math import pi
    import matplotlib.pyplot as plt
    from scipy.misc import imread
    import matplotlib.cbook as cbook
    
    # Numbers of European Roulette Wheel
    cat = [0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26]
    
    # Hit frequency of each number
    values = [108, 116, 102, 100, 102, 107, 115, 114, 110, 102, 114, 101, 121, 103, 121, 105, 104, 117, 108, 121, 122, 97, 114, 122, 98, 105, 114, 111, 129, 123, 107, 112, 124, 102, 124, 109, 107]
    
    N = len(cat)
    x_as = [n / float(N) * 2 * pi for n in range(N)]
    
    # Because our chart will be circular we need to append a copy of the first 
    # value of each list at the end of each list with data
    values += values[:1]
    x_as += x_as[:1]
    
    # Set color of axes
    plt.rc('axes', linewidth=0.5, edgecolor="#888888")
    
    # Create polar plot
    ax = plt.subplot(111, polar=True)
    
    # Set clockwise rotation. That is:
    ax.set_theta_offset(pi / 2)
    ax.set_theta_direction(-1)
    
    # Set position of y-labels
    ax.set_rlabel_position(0)
    
    # Set color and linestyle of grid
    ax.xaxis.grid(True, color="#888888", linestyle=':', linewidth=0.5)
    ax.yaxis.grid(True, color="#888888", linestyle=':', linewidth=0.5)
    
    # Set number of radial axes and remove labels
    plt.xticks(x_as[:-1], [])
    
    # Set yticks
    tickInt = []
    tickStr = []
    y = 0
    maxHitFrequency = max(values)
    
    while y <= maxHitFrequency:
        tickInt.append(y)
        tickStr.append(str(y))
        y += 25
    
    plt.yticks(tickInt, tickStr)
    
    # Plot data
    ax.plot(x_as, values, linewidth=0, linestyle='solid', zorder=3)
    
    # Fill area
    ax.fill(x_as, values, 'b', alpha=0.45, color="#006600")
    
    # Set axes limits
    plt.ylim(0, y)   
    
    plt.show()
    

    我想让情节以类似以下的图像为边界: enter image description here

    下面是我尝试过但没有成功的代码:

    # Display Image
    datafile = cbook.get_sample_data('D:\AR Wheel Vector.jpg')
    img = imread(datafile)
    plt.imshow(img)
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   ImportanceOfBeingErnest    6 年前

    我认为很难将图像准确定位在需要的位置,以适合极坐标图。因此,我宁愿尝试在matplotlib情节中重新创建轮盘赌板。

    enter image description here

    这个想法主要是创建许多交替颜色的矩形,并将数字作为文本放入其中。通过使用θ轴的轴变换可以很容易地实现这一点, ax.get_xaxis_tranform() ,使角度坐标为角度(数据单位),径向坐标为轴坐标( 0 1 轴内)。

    import numpy as np
    import matplotlib.pyplot as plt
    
    # Numbers of European Roulette Wheel
    cat = [0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5,
           24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26]
    
    # Hit frequency of each number
    values = [108, 116, 102, 100, 102, 107, 115, 114, 110, 102, 114, 101, 121, 103, 
              121, 105, 104, 117, 108, 121, 122, 97, 114, 122, 98, 105, 114, 111, 129, 
              123, 107, 112, 124, 102, 124, 109, 107]
    
    N = len(cat)
    x_as = [n / float(N) * 2 *  np.pi for n in range(N)]
    
    # Because our chart will be circular we need to append a copy of the first 
    # value of each list at the end of each list with data
    values += values[:1]
    x_as += x_as[:1]
    
    # Set color of axes
    plt.rc('axes', linewidth=0.5, edgecolor="#888888")
    
    # Create polar plot
    ax = plt.subplot(111, polar=True)
    
    # Set clockwise rotation. That is:
    ax.set_theta_offset(np.pi / 2)
    ax.set_theta_direction(-1)
    
    # Set position of y-labels
    ax.set_rlabel_position(0)
    
    # Set color and linestyle of grid
    ax.xaxis.grid(True, color="#888888", linestyle=':', linewidth=0.5)
    ax.yaxis.grid(True, color="#888888", linestyle=':', linewidth=0.5)
    
    # Set number of radial axes and remove labels
    plt.xticks(x_as[:-1], [])
    
    ## Set yticks
    yticks = np.arange(0,max(values),25)
    plt.yticks(yticks, yticks)
    
    # Plot data
    ax.plot(x_as, values, linewidth=0, linestyle='solid', zorder=3)
    
    # Fill area
    ax.fill(x_as, values, 'b', alpha=0.45, color="#006600")
    
    # Set axes limits
    plt.ylim(0, np.ceil(max(values)/25.)*25) 
    
    
    x_bin = np.array(x_as)[:-1]-np.diff(x_as)[0]/2.
    c = ["#fe0000" if i%2 else "#000000" for i in range(len(x_bin))]
    c[0] = "#007f0e"
    for i in range(len(x_bin)):
        rec = plt.Rectangle([x_bin[i],1],np.diff(x_as)[0],0.22 ,
                        transform=ax.get_xaxis_transform(), 
                        color=c[i], clip_on=False)
        ax.add_patch(rec)
        ax.text(x_as[i], 1.1, cat[i],transform=ax.get_xaxis_transform(),
                ha="center", va="center", color="w", size=12, weight='bold', family="serif",
                rotation_mode="anchor", rotation=-np.rad2deg(x_as[i]))
    
    ang = np.linspace(0,2*np.pi,200)
    kw = dict(clip_on=False, lw=3,transform=ax.get_xaxis_transform())
    ax.plot(ang,np.ones_like(ang), color="k", **kw)
    ax.plot(ang,np.ones_like(ang)*1.22, color="w",**kw)
    
    plt.show()