使用pandas plot方法设置图形大小时的不一致性

2024-04-25 14:43:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图利用熊猫数据框的绘图方法的便利性,同时调整生成的图形的大小。(我正在将这些数据保存到文件中,并将它们显示在Jupyter笔记本中)。我发现下面的方法大多数时候都是成功的,除了我在同一个图表上绘制两条线时-然后图回到默认大小。

我怀疑这可能是由于序列上的plot和数据帧上的plot之间的差异造成的。

安装示例代码:

data = {
    'A': 90 + np.random.randn(366),
    'B': 85 + np.random.randn(366)
}

date_range = pd.date_range('2016-01-01', '2016-12-31')

index = pd.Index(date_range, name='Date')

df = pd.DataFrame(data=data, index=index)

控件-此代码生成预期结果(宽图):

fig = plt.figure(figsize=(10,4))

df['A'].plot()
plt.savefig("plot1.png")
plt.show()

结果:

plot1.png

绘制两条线-图形大小不是(10,4)

fig = plt.figure(figsize=(10,4))

df[['A', 'B']].plot()
plt.savefig("plot2.png")
plt.show()

结果:

plot2.png

正确的方法是什么,这样无论选择了多少系列,图形大小都是一致性集?


Tags: 数据方法图形dfdatadateindexplot
2条回答

始终在FigureAxes对象上显式直接操作。不要依赖于pyplot状态机。就你而言,这意味着:

fig1, ax1 = plt.subplots(figsize=(10,4))
df['A'].plot(ax=ax1)
fig1.savefig("plot1.png")


fig2, ax2 = plt.figure(figsize=(10,4)) 
df[['A', 'B']].plot(ax=ax2)
fig2.savefig("plot2.png")

plt.show()

这两种情况不同的原因是隐藏在pandas.DataFrame.plot()逻辑中的一点。正如在the documentation中可以看到的,这个方法允许传递很多参数,这样它就可以处理各种不同的情况。

在第一种情况下,通过fig = plt.figure(figsize=(10,4))创建matplotlib图,然后绘制一个单列数据帧。现在pandas plot函数的内部逻辑是检查matplotlib状态机中是否已经存在一个图形,如果已经存在,则使用它的当前轴将列值绘制到该图形。这和预期的一样。

但是在第二种情况下,数据由两列组成。有几个选项可以处理这样的绘图,包括使用具有共享轴或非共享轴的不同子块等。为了使熊猫能够应用这些可能的要求中的任何一个,它将在默认情况下创建一个新的图形,可以将要绘图的轴添加到该图形中。除非指定figsize参数,否则新图形将不知道已存在的图形及其大小,而是具有默认大小。

在注释中,您说一个可能的解决方案是使用df[['A', 'B']].plot(figsize=(10,4))。这是正确的,但是您需要省略初始图形的创建。否则它将产生两个数字,这可能是不希望的。在笔记本中,这是不可见的,但是如果您以通常的python脚本的方式运行它,并在最后使用plt.show(),将会有两个图形窗口打开。

因此,让熊猫负责创造形象的解决方案是

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"A":[2,3,1], "B":[1,2,2]})
df[['A', 'B']].plot(figsize=(10,4))

plt.show()

避免创建新图形的一种方法是为ax函数提供pandas.DataFrame.plot(ax=ax)参数,其中ax是外部创建的轴。此轴可以是通过plt.gca()获得的标准轴。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"A":[2,3,1], "B":[1,2,2]})
plt.figure(figsize=(10,4))
df[['A', 'B']].plot(ax = plt.gca())

plt.show()

或者使用answer from PaulH中所示的更面向对象的方式。

相关问题 更多 >