如何在matplotlib图例中动态重新排序项目?

时间:2017-11-22 20:49:21

标签: python python-2.7 matplotlib

我正在尝试创建一个简单的凹凸图表,其中图例顺序将由最近观察的排名决定。我有一个pandas DataFrame“y”,其中行的排名看起来像这样。

In[231]: y
Out[231]: 
Currency    AUD  CAD   CHF  EUR  GBP  JPY  NOK  NZD  SEK   USD
2017-09-08  5.0  1.0   8.0  3.0  9.0  7.0  4.0  6.0  2.0  10.0
2017-09-22  8.0  2.0  10.0  1.0  5.0  9.0  4.0  6.0  3.0   7.0
2017-10-06  4.0  5.0  10.0  2.0  7.0  9.0  3.0  8.0  1.0   6.0
2017-10-20  3.0  4.0  10.0  1.0  7.0  5.0  6.0  9.0  2.0   8.0
2017-11-03  5.0  3.0  10.0  1.0  9.0  7.0  2.0  8.0  4.0   6.0
2017-11-17  5.0  4.0  10.0  1.0  9.0  7.0  3.0  8.0  2.0   6.0

到目前为止我使用过的代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

fig = plt.figure(figsize=(8.5,8.5))
ax = fig.add_subplot(111)

l1,l2,l3,l4,l5,l6,l7,l8,l9,l10 = ax.plot_date(y.index.to_pydatetime(), y, '*-') 
ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=(4),interval=2))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d'))
ax.yaxis.set_ticks(np.arange(1, 11, 1))
ax.set_title('Sample Chart', fontsize=20)
plt.gca().invert_yaxis()
fig.legend([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10], ['AUD','CAD','CHF','EUR','GBP','JPY','NOK','NZD','SEK','USD'], 'right', fontsize=16, frameon=False, labelspacing=1.4)
plt.tight_layout(pad=10) 

生成的输出 fig.png

我的问题是如何根据“2017-11-17”的最后一次观察重新排序图例?即我想要欧元,瑞典克朗,挪威克朗等...我不想要一个静态字母顺序。基本上在fig.legend中我需要[l4,l9,l7,...,l3],虽然这个列表会在行添加到'y'时重新排序。我可以很容易地生成一个具有正确排序顺序的列表,但是fig.legend不会接受元素在引号中的列表,即['l4','l9','l7',...,'l3']。

我可能正在接近这个完全错误,所以任何帮助都会很棒。

1 个答案:

答案 0 :(得分:0)

您需要按照数据框的最后一行(或任何其他行)的排序结果来排序要用作图例句柄的行列表以及标签列表。

lines = ax.plot_date(...) 
lastrow = y.iloc[-1,:].values 
order = np.argsort(lastrow)
fig.legend(np.array(lines)[order], y.columns[order])

完整示例:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

fig, ax = plt.subplots(figsize=(6.4,3))

lines = ax.plot_date(y.index.to_pydatetime(), y, '*-') 
ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=(4),interval=2))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d'))
ax.yaxis.set_ticks(np.arange(1, 11, 1))

plt.gca().invert_yaxis()

lastrow = y.iloc[-1,:].values 
order = np.argsort(lastrow)
fig.legend(np.array(lines)[order], y.columns[order], loc='right', frameon=False)
plt.subplots_adjust(right=0.85)
plt.show()

enter image description here