matplotlib - making labels for violin plots

∥☆過路亽.° 提交于 2019-12-08 18:04:30

问题


I usually make labels for bars in the following manner using parameter 'label' in the method 'bar'.

axes[0].bar(x, y, bar_width, label='abc')
axes[0].legend()

Now I'd like to plot violin plots and make label for each collection as follows, but it doesn't work since 'violinplot' doesn't have the parameter 'label'.

axes[0].violinplot(data1, label='abc1')
axes[1].violinplot(data2, label='abc2')

Can anyone help me out to make a label for each collection?


回答1:


As it was mentioned in comment, some plots in matplotlib don't support legends. Documentation still provides a simple way to add custom legends for them: http://matplotlib.org/users/legend_guide.html#proxy-legend-handles

Main idea : add 'fake' objects, which can be not shown in the plot, then use it to form a handles list for legend method.

    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()




回答2:


edit: sorry, I now see that you wanted to add a legend, not axis labels...

You can manually set the tick locations and then overwrite their labels:

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)




回答3:


Here is my solution for multple violin plots. Note that it grabs the patch color from the first shaded area of the given violin plot---this could be changed to do something else if there are multiple colors, or you could instead grab the color of the vertical bar with 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)



来源:https://stackoverflow.com/questions/33864578/matplotlib-making-labels-for-violin-plots

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!