4

我有一个band1如下所示的字典,我想根据字典中每个列表的第一个和最后一个元素打印出一个图表。x 轴上每个列表的第一个元素是频率,最后一个元素是接收强度,应该在 y 轴上。例如,10812 的强度为 16 等

band1 = {'channel1': [10564, 2112.8, 1922.8, 0],
         'channel10': [10787, 2157.4, 1967.4, 11],
         'channel11': [10812, 2162.4, 1972.4, 16],
         'channel12': [10837, 2167.4, 1977.4, 46],
         'channel2': [10589, 2117.8, 1927.8, 29],
         'channel3': [10612, 2122.4, 1932.4, 0],
         'channel4': [10637, 2127.4, 1937.4, 40],
         'channel5': [10662, 2132.4, 1942.4, 54],
         'channel6': [10687, 2137.4, 1947.4, 0],
         'channel7': [10712, 2142.4, 1952.4, 50],
         'channel8': [10737, 2147.4, 1957.4, 19],
         'channel9': [10762, 2152.4, 1962.4, 24]}

我对此进行排序没有问题,channel1 -> channel12 但是有什么好方法可以打印漂亮的图表,字典中的条目数量可能会随着通道的增加或减少而变化。

4

1 回答 1

6

这是一个点图算法,尽可能简单和幼稚。当然,它的性能还远远没有被执行并且可以优化,并且输出可能有一些轴和数字。

HEIGHT = 10
WIDTH = 40
MARKER = '*'
FILL_CHARACTER = ' '

coords = [(ch[0], ch[3]) for ch in band1.values()]


# Convert to coordinates of a desired ASCII area

xmin = min(c[0] for c in coords)
xmax = max(c[0] for c in coords)
kx = (WIDTH - 1)  / (xmax - xmin)

ymin = min(c[1] for c in coords)
ymax = max(c[1] for c in coords)
ky = (HEIGHT - 1) / (ymax - ymin)

acoords = [(round((c[0] - xmin) * kx),
            round((c[1] - ymin) * ky)) for c in coords]

# Actually draw the graph

for y in range(HEIGHT, -1, -1):
    chars = []
    for x in range(WIDTH):
        if (x, y) in acoords:
            chars.append(MARKER)
        else:
            chars.append(FILL_CHARACTER)
    print(''.join(chars))

结果:

              *                         
                     *                 *
          *                             

    *                                   
                            *           
                         *         *    
                                *       

*      *          *                     

如果 x 坐标是唯一的,则可以很容易地对其进行修改以绘制柱状图或折线图。

例如对于酒吧的情况:

HEIGHT = 10
WIDTH = 40
MARKER = '*'
FILL_CHARACTER = ' '

coords = [(ch[0], ch[3]) for ch in band1.values()]
coords.sort(key=lambda ch: ch[1])

xmin = min(c[0] for c in coords)
xmax = max(c[0] for c in coords)
kx = (WIDTH - 1)  / (xmax - xmin)

ymin = min(c[1] for c in coords)
ymax = max(c[1] for c in coords)
ky = (HEIGHT - 1) / (ymax - ymin)

acoords = {}
for c in coords:
    x = round((c[0] - xmin) * kx)
    y = round((c[1] - ymin) * ky)
    if x not in acoords:
        acoords[x] = y
    else:
        acoords[x] = max(acoords[x], y)

for y in range(HEIGHT, -1, -1):
    chars = []
    for x in range(WIDTH):
        if acoords.get(x, 0) >= y:
            chars.append(MARKER)
        else:
            chars.append(FILL_CHARACTER)
    print(''.join(chars))

结果:

              *                         
              *      *                 *
          *   *      *                 *
          *   *      *                 *
    *     *   *      *                 *
    *     *   *      *      *          *
    *     *   *      *   *  *      *   *
    *     *   *      *   *  *   *  *   *
    *     *   *      *   *  *   *  *   *
****************************************
于 2013-04-26T16:35:56.443 回答