【问题标题】:Plotting lists with different number of elements in matplotlib在 matplotlib 中绘制具有不同数量元素的列表
【发布时间】:2017-06-26 01:24:45
【问题描述】:

我有一个 numpy 数组列表,每个数组可能有不同数量的元素,例如:

[array([55]),
 array([54]),
 array([], dtype=float64),
 array([48, 55]),]

我想绘制此图,其中每个数组都分配了一个横坐标(x 值),例如 [1,2,3,4],因此该图应显示以下几点:[[1,55], [2, 54], [4, 48], [4, 55]]。 有没有办法用 matplotlib 做到这一点?或者如何先用 numpy 或 pandas 转换数据以便绘制?

【问题讨论】:

    标签: pandas numpy matplotlib


    【解决方案1】:

    您要做的是链接原始数组并生成一个带有“横坐标”的新数组。连接的方法有很多,最有效的方法之一是使用 itertools.chain

    import itertools
    from numpy import array
    
    x = [array([55]), array([54]), array([]), array([48, 55])]
    
    ys = list(itertools.chain(*x))
    # this will be [55, 54, 48, 55]
    
    # generate abscissas
    xs = list(itertools.chain(*[[i+1]*len(x1) for i, x1 in enumerate(x)])) 
    

    现在您可以使用 matplotlib 轻松绘图,如下所示

    import matplotlib.pyplot as plt
    plt.plot(xs, ys)
    

    【讨论】:

    • 并非如此。在这种情况下,我需要将最后两个元素 48 和 55 关联到同一个横坐标(同一个 x)。
    • 如果您想绘制单独的行,我已经更改了上面的代码。不太确定您要绘制什么,但上面会做
    • 这行得通,但要按要求获得xs = [1, 2, 4, 4],您需要使用[[i+1]*len(x1) for i, x1 in enumerate(x)]。 (目前,它给了[0, 1, 3, 3]
    【解决方案2】:

    如果你想对不同的数据组有不同的标记(颜色由matplotlib自动循环):

    import numpy as np
    import matplotlib.pyplot as plt
    
    markers = ['o', #'circle',
               'v', #'triangle_down',
               '^', #'triangle_up',
               '<', #'triangle_left',
               '>', #'triangle_right',
               '1', #'tri_down',
               '2', #'tri_up',
               '3', #'tri_left',
               '4', #'tri_right',
               '8', #'octagon',
               's', #'square',
               'p', #'pentagon',
               'h', #'hexagon1',
               'H', #'hexagon2',
               'D', #'diamond',
               'd', #'thin_diamond'
               ]
    
    n_markers = len(markers)
    
    a = [10.*np.random.random(int(np.random.random()*10)) for i in xrange(n_markers)]
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    for i, data in enumerate(a):
        xs = data.shape[0]*[i,]  # makes the abscissas list
        marker = markers[i % n_markers] # picks a valid marker
        ax.plot(xs, data, marker, label='data %d, %s'%(i, marker))
    
    ax.set_xlim(-1, 1.4*len(a))
    ax.set_ylim(0, 10)
    ax.legend(loc=None)
    fig.tight_layout()
    

    请注意,y 刻度的限制是硬编码的,请进行相应更改。 1.4*len(a) 是为了在图表的右侧为图例留出空间。

    上面的示例在x=0(将是深蓝色圆圈)中没有意义,因为其数据集的随机分配大小为零,但如果您不想使用,可以轻松放置+1 x=0.

    【讨论】:

      【解决方案3】:

      当数组为空或比列表中最长的数组短时,使用 pandas 创建一个插入 nans 的 numpy 数组...

      import numpy as np
      import pandas as pd
      import matplotlib.pyplot as plt
      
      arr_list = [np.array([55]),
                  np.array([54]),
                  np.array([], dtype='float64'),
                  np.array([48, 55]),]
      
      df = pd.DataFrame(arr_list)
      list_len = len(df)
      repeats = len(list(df))
      vals = df.values.flatten()
      xax = np.repeat(np.arange(list_len) + 1, repeats)
      df_plot = pd.DataFrame({'xax': xax, 'vals': vals})
      plt.scatter(df_plot.xax, df_plot.vals);
      

      【讨论】:

        【解决方案4】:

        x 你的名单:

        [plt.plot(np.repeat(i,len(x[i])), x[i],'.') for i in range(len(x))]
        plt.show()
        

        【讨论】:

        • 调用列表list
        • 你是对的,这只是为了示例:)
        • 谢谢,但我的实际列表非常大,我认为多次调用plot 效率不高。
        【解决方案5】:

        @Alessandro Mariani 基于 itertools 的回答让我想到了另一种方法来生成包含我需要的数据的数组。在某些情况下,它可能更紧凑。也是基于itertools.chain

        import itertools
        from numpy import array
        
        y = [array([55]), array([54]), array([]), array([48, 55])]
        x = array([1,2,3,4])
        d = array(list(itertools.chain(*[itertools.product([t], n) for t, n in zip(x,y)])))
        

        d 现在是以下数组:

        array([[ 1, 55],
               [ 2, 54],
               [ 4, 48],
               [ 4, 55]])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-03
          • 2020-07-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多