3

我很难添加图例matplotlib.pyplot,我的目标是使平行坐标图类似于

Matplotlib 中的平行坐标图

由于我的用例相似,我使用了提供的解决方案,除了我只有 2 个观察值,每组 1 个并且我添加了 plt.legend(axes,style),因此创建了图例,但是当我运行代码时,我收到以下警告并且没有传奇。

:\Python27\lib\site-packages\matplotlib\legend.py:634: UserWarning: Legend 不支持实例。可以使用代理艺术家代替。请参阅:http : //matplotlib.org/users/legend_guide.html#using-proxy-artist "#using-proxy-artist".format(orig_handle)

我试图浏览文档,但找不到解决方案。

我发现了下面列出的另一篇 stackoverflow 帖子,但仍然不太清楚图例的用法,尤其是关于如何在传递给图例函数之前解压缩子图。谁能解释一下它是如何工作的。

在图例、matplotlib、Python 中使用代理艺术家

#!/usr/bin/python
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

def parallel_coordinates(data_sets, style=None):

    dims = len(data_sets[0])
    x    = range(dims)
    fig, axes = plt.subplots(1, dims-1, sharey=False)

    if style is None:
        style = ['r-']*len(data_sets)

    # Calculate the limits on the data
    min_max_range = list()
    for m in zip(*data_sets):
        mn = min(m)
        mx = max(m)
        if mn == mx:
            mn -= 0.5
            mx = mn + 1.
        r  = float(mx - mn)
        min_max_range.append((mn, mx, r))

    # Normalize the data sets
    norm_data_sets = list()
    for ds in data_sets:
        nds = [(value - min_max_range[dimension][0]) / 
                min_max_range[dimension][2] 
                for dimension,value in enumerate(ds)]
        norm_data_sets.append(nds)
    data_sets = norm_data_sets

    # Plot the datasets on all the subplots
    for i, ax in enumerate(axes):
        for dsi, d in enumerate(data_sets):
            ax.plot(x, d, style[dsi])
        ax.set_xlim([x[i], x[i+1]])

    # Set the x axis ticks 
    for dimension, (axx,xx) in enumerate(zip(axes, x[:-1])):
        axx.xaxis.set_major_locator(ticker.FixedLocator([xx]))
        ticks = len(axx.get_yticklabels())
        labels = list()
        step = min_max_range[dimension][2] / (ticks - 1)
        mn   = min_max_range[dimension][0]
        for i in xrange(ticks):
            v = mn + i*step
            labels.append('%4.2f' % v)
        axx.set_yticklabels(labels)


    # Move the final axis' ticks to the right-hand side
    axx = plt.twinx(axes[-1])
    dimension += 1
    axx.xaxis.set_major_locator(ticker.FixedLocator([x[-2], x[-1]]))
    ticks = len(axx.get_yticklabels())
    step = min_max_range[dimension][2] / (ticks - 1)
    mn   = min_max_range[dimension][0]
    labels = ['%4.2f' % (mn + i*step) for i in xrange(ticks)]
    axx.set_yticklabels(labels)

    # Stack the subplots 

    plt.subplots_adjust(wspace=0)
    plt.legend(axes,style)
    return plt

if __name__ == '__main__':
    import random
    base  = [0,   0,  5,   5,  0]
    scale = [1.5, 2., 1.0, 2., 2.]
    data = [[base[x] + random.uniform(0., 1.)*scale[x]
            for x in xrange(5)] for y in xrange(1)]
    colors = ['r'] * 1

    base  = [3,   6,  0,   1,  3]
    scale = [1.5, 2., 2.5, 2., 2.]
    data.extend([[base[x] + random.uniform(0., 1.)*scale[x]
                 for x in xrange(5)] for y in xrange(1)])
    colors.extend(['b'] * 1)


    parallel_coordinates(data, style=colors).show()
4

1 回答 1

0

基本上错误是因为matplotlib不支持程序生成图例,并且告诉您必须手动执行此操作。例如

blue_line = mlines.Line2D([], [], color='blue', label='Blue')
red_line = mlines.Line2D([], [], color='red', label='Red')
plt.legend(handles=[blue_line, red_line])

这依赖于导入matplotlib.linesmlines. 在有问题的代码中,这将生成

如果您更喜欢补丁而不是线条,也可以使用matplotlib.patches,即

blue_patch = mpatches.Patch(color='blue', label='Blue')
red_patch = mpatches.Patch(color='red', label='Red')
plt.legend(handles=[blue_patch, red_patch])

这依赖于导入matplotlib.patchesmpatches. 这会产生

您可以将handles所需的任何自定义添加到图例中 - 混合补丁、线条和标记是可以接受的。

于 2018-12-30T00:17:57.903 回答