我正在尝试创建一个简单的凹凸图表,其中图例顺序将由最近观察的排名决定。我有一个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']。
我可能正在接近这个完全错误,所以任何帮助都会很棒。
答案 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()