Matplotlib:使用包含子图的自定义绘图功能在同一图形中循环绘图

dojqjjoe  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(130)

我有一个具有多个ID的数据框,希望为每个ID创建一个断轴图。我还希望在同一图中绘制所有内容,而不是为每个ID创建单独的图。我的玩具示例生成单独的图,但我更希望两个图重叠,如下面的小图所示

df = pd.DataFrame({'id':['id1','id1','id1','id1','id1','id1','id1','id1','id1','id1',
                   'id2','id2','id2','id2','id2','id2','id2','id2','id2','id2'],
               'x': [0, 1, 2, 3, 4, 5, 1000, 2000, 3000, 4000,
                     0, 1, 2, 3, 4, 5, 1000, 2000, 3000, 4000,],
               'y': [5, 4, 5, 4, 7, 6, 5, 4, 3, 2,
                     1, 2, 3, 4, 7, 7, 8, 7, 9, 5]})

def _custom_plot(frame):
    x = frame['x']
    y = frame['y']
    
    f,(ax,ax2) = plt.subplots(1,2,sharey=True, facecolor='w', figsize=(15, 5))

    # plot the same data on both axes
    ax.plot(x, y, 'o--', color='grey', alpha=0.3)
    ax2.plot(x, y, 'o--', color='grey', alpha=0.3)

    ax.set_xlim(0,100)
    ax2.set_xlim(1e3,5e3)

    # hide the spines between ax and ax2
    ax.spines['right'].set_visible(False)
    ax2.spines['left'].set_visible(False)
    ax.yaxis.tick_left()
    #ax.tick_params(labelright='off')
    ax2.yaxis.tick_right()

    d = .015 # how big to make the diagonal lines in axes coordinates
    # arguments to pass plot, just so we don't keep repeating them
    kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
    ax.plot((1-d,1+d), (-d,+d), **kwargs)
    ax.plot((1-d,1+d),(1-d,1+d), **kwargs)

    kwargs.update(transform=ax2.transAxes)  # switch to the bottom axes
    ax2.plot((-d,+d), (1-d,1+d), **kwargs)
    ax2.plot((-d,+d), (-d,+d), **kwargs)
    
    plt.yticks([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
    
    plt.show()
        

for id in df['id'].unique():
    _custom_plot(df[df['id']==id])

kkbh8khc

kkbh8khc1#

我不确定你的评论@cphlewis是否朝着这个方向去了,但我想通了这样的工作方式

df = pd.DataFrame({'id':['id1','id1','id1','id1','id1','id1','id1','id1','id1','id1', 'id2','id2','id2','id2','id2','id2','id2','id2','id2','id2'],
                   'x': [0, 1, 2, 3, 4, 5, 1000, 2000, 3000, 4000, 0, 1, 2, 3, 4, 5, 1000, 2000, 3000, 4000,],
                   'y': [5, 4, 5, 4, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 7, 7, 8, 7, 9, 5]})

def _sub_plot(frame, ax=None):
    x = frame['x']
    y = frame['y']
    
    if ax is None:
        ax = plt.gca()
    
    # plot the same data on both axes
    line = ax.plot(x, y, 'o--', color='grey', alpha=0.3)
    
    return line

    
def _main_plot(df, listofkeys, key):
    f,(ax1,ax2) = plt.subplots(1,2,sharey=True, facecolor='w', figsize=(15, 5))
    
    for l in listofkeys:
        frame = df[df[key] == l]
        
        _sub_plot(frame, ax1)
        _sub_plot(frame, ax2)

        ax1.set_xlim(0,100)
        ax2.set_xlim(1e3,5e3)

        # hide the spines between ax and ax2
        ax1.spines['right'].set_visible(False)
        ax2.spines['left'].set_visible(False)
        ax1.yaxis.tick_left()
        #ax.tick_params(labelright='off')
        ax2.yaxis.tick_right()

        d = .015 # how big to make the diagonal lines in axes coordinates
        # arguments to pass plot, just so we don't keep repeating them
        kwargs = dict(transform=ax1.transAxes, color='k', clip_on=False)
        ax1.plot((1-d,1+d), (-d,+d), **kwargs)
        ax1.plot((1-d,1+d),(1-d,1+d), **kwargs)

        kwargs.update(transform=ax2.transAxes)  # switch to the bottom axes
        ax2.plot((-d,+d), (1-d,1+d), **kwargs)
        ax2.plot((-d,+d), (-d,+d), **kwargs)

        plt.yticks([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])

_main_plot(df, df['id'].unique(), 'id')

相关问题