matplotlib-为小提琴图制作标签

Han*_*Han 7 python label matplotlib

我通常使用“ bar”方法中的参数“ label”以以下方式为条形标签。

axes[0].bar(x, y, bar_width, label='abc')
axes[0].legend()
Run Code Online (Sandbox Code Playgroud)

现在,我想按以下方式绘制小提琴图并为每个集合制作标签,但是由于“ violinplot”没有参数“ label”,因此它不起作用。

axes[0].violinplot(data1, label='abc1')
axes[1].violinplot(data2, label='abc2')
Run Code Online (Sandbox Code Playgroud)

谁能帮我为每个收藏贴上标签?

Ian*_*cks 10

这是我对多个小提琴图的解决方案。请注意,它从给定小提琴图的第一个阴影区域获取补丁颜色——如果有多种颜色,可以将其更改为执行其他操作,或者您可以使用violin["cbars"].get_color().flatten().

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np

labels = []
def add_label(violin, label):
    color = violin["bodies"][0].get_facecolor().flatten()
    labels.append((mpatches.Patch(color=color), label))


positions = np.arange(3,13,3)
data = np.random.randn(1000, len(positions))
add_label(plt.violinplot(data, positions), "Flat")    

positions = np.arange(1, 10, 2)
data = np.random.randn(1000, len(positions)) + positions
add_label(plt.violinplot(data, positions), "Linear")

positions = np.arange(2, 11, 1)
data = np.random.randn(1000, len(positions)) + positions ** 2 / 4
add_label(plt.violinplot(data, positions), "Quadratic")

plt.legend(*zip(*labels), loc=2)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


mer*_*tta 6

正如评论中提到的,matplotlib中的某些图不支持图例。文档仍然提供了一种为它们添加自定义图例的简单方法:http : //matplotlib.org/users/legend_guide.html#proxy-legend-handles

主要思想:添加“假”对象,该对象无法在图中显示,然后使用它形成图例方法的句柄列表。

    import random
    import numpy as np
    import matplotlib.pyplot as pl
    import matplotlib.patches as mpatches
    from itertools import repeat

    red_patch = mpatches.Patch(color='red')
    # 'fake' invisible object

    pos   = [1, 2, 4, 5, 7, 8]
    label = ['plot 1','plot2','ghi','jkl','mno','pqr']
    data  = [np.random.normal(size=100) for i in pos]

    fake_handles = repeat(red_patch, len(pos))

    pl.figure()
    ax = pl.subplot(111)
    pl.violinplot(data, pos, vert=False)
    ax.legend(fake_handles, label)
    pl.show()
Run Code Online (Sandbox Code Playgroud)

带自定义图例的小提琴图


小智 6

有一个比@Ian Hincks 代码更简单的解决方案,无需使用 mpatches

import matplotlib.pyplot as plt
import numpy as np

positions = np.arange(3,13,3)
data = np.random.randn(1000, len(positions))
vp1 = plt.violinplot(data, positions) 

positions = np.arange(1, 10, 2)
data = np.random.randn(1000, len(positions)) + positions
vp2 = plt.violinplot(data, positions)

positions = np.arange(2, 11, 1)
data = np.random.randn(1000, len(positions)) + positions ** 2 / 4
vp3 = plt.violinplot(data, positions)

plt.legend([vp1['bodies'][0],vp2['bodies'][0], vp3['bodies'][0]], ['flat', 'linear', 'quadratic'], loc=2)[enter image description here][1]
Run Code Online (Sandbox Code Playgroud)

使用线条代替身体替换vp1['bodies'][0]vp1['cbars']

演示:带有标签的小提琴图


Bar*_*art 5

编辑:抱歉,我现在看到您想添加图例,而不是轴标签......

您可以手动设置刻度位置,然后覆盖它们的标签:

import numpy as np
import matplotlib.pyplot as pl

pos   = [1, 2, 4, 5, 7, 8]
label = ['abc','def','ghi','jkl','mno','pqr']
data  = [np.random.normal(size=100) for i in pos]

pl.figure()
ax = pl.subplot(111)
pl.violinplot(data, pos, vert=False)
ax.set_yticks(pos)
ax.set_yticklabels(label)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述