难以合并和重新定位Matplotlib和Pandas中的两个图表的传说
问题描述
我正在尝试将两个图表绘制到一个图形上,这两个图表来自同一个数据框,但一个表示为堆叠条形图,另一个表示为简单的线形图。
当我使用以下代码创建绘图时:
combined.iloc[:, 1:10].plot(kind='bar', stacked=True, figsize=(20,10))
combined.iloc[:, 0].plot(kind='line', secondary_y=True, use_index=False, linestyle='-', marker='o')
plt.legend(loc='upper left', fancybox=True, framealpha=1, shadow=True, borderpad=1)
plt.show()
combined
数据框如下:
我看到以下图片:
我正在尝试将两个图例合并为一个图例,并将图例放置在左上角,以便所有图表都可见。
谁能解释一下为什么plt.legend()
似乎只在编辑我的combined
数据帧的combined.iloc[:, 0]
切片对应的折线图?如果任何人能看到一种快速简单的方法来组合和重新定位传说,请让我知道!我将不胜感激。
解决方案
参数True
传递True
意味着绘图将在具有双x轴的单独的轴实例上创建,因为这会创建一个不同的轴实例。解决方案通常是手动创建图例,如linked@ImportanceOfBeingErnest对问题的回答所示。如果您不想直接创建图例,可以通过在调用pandas.DataFrame.plot
之间调用plt.legend()
并存储结果来解决此问题。然后,您可以从两个轴实例中恢复控制柄和标签。以下代码是这方面的完整示例
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame({'x' : np.random.random(25),
'y' : np.random.random(25)*5,
'z' : np.random.random(25)*2.5})
df.iloc[:, 1:10].plot(kind='bar', stacked=True)
leg = plt.legend()
df.iloc[:, 0].plot(kind='line', y='x', secondary_y=True)
leg2 = plt.legend()
plt.legend(leg.get_patches()+leg2.get_lines(),
[text.get_text() for text in leg.get_texts()+leg2.get_texts()],
loc='upper left', fancybox=True, framealpha=1, shadow=True, borderpad=1)
leg.remove()
plt.show()
这将产生
并且应该相当容易修改,以适应您的特定使用情形。
您也可以使用matplotlib.pyplot.figlegend()
,但您需要在所有调用中传递legend = False
到pandas.DataFrame.plot()
,即
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame({'x' : np.random.random(25),
'y' : np.random.random(25)*5,
'z' : np.random.random(25)*2.5})
df.iloc[:, 1:10].plot(kind='bar', stacked=True, legend=False)
df.iloc[:, 0].plot(kind='line', y='x', secondary_y=True, legend=False)
plt.figlegend(loc='upper left', fancybox=True, framealpha=1, shadow=True, borderpad=1)
plt.show()
这将默认将图例定位在轴之外,但您可以通过调用plt.figlegend()
中的bbox_to_anchor
参数覆盖自动定位。
相关文章