为啥我不能将 x 和 y 标签设置为 pd.plot() 的参数,而我可以轻松设置类似的东西,例如标题?

Posted

技术标签:

【中文标题】为啥我不能将 x 和 y 标签设置为 pd.plot() 的参数,而我可以轻松设置类似的东西,例如标题?【英文标题】:Why can't I set x and y labels as arguments to pd.plot(), whereas I can easily set similar stuff, such as title?为什么我不能将 x 和 y 标签设置为 pd.plot() 的参数,而我可以轻松设置类似的东西,例如标题? 【发布时间】:2017-12-08 21:31:54 【问题描述】:

我正在用 pandas 打印各种东西,使用内置的 plot 命令,例如在 ipython 中 my_dataframe.plot() 后跟 plt.show()

现在这是一种非常简单方便的可视化方式,而且考虑到我还是对 SVG 文件进行后处理,我不太关心情节的细节。

但是,我需要一个标题、一个图例和绘图上 x 和 y 轴的标签,既可以提醒自己什么是什么,也可以快速将一些东西发送给其他人,而无需添加“哦,顺便说一句,x 轴这次是小时,y 一如既往地是米,但现在蓝色是样本 B……”电子邮件中的一行。

我想出了如何以一种简单的方式做到这一点(见下文),我也知道我可以用ax 做的各种强大的事情,但我花了一段时间才达到我的“简单”解决方案,我远离ax,因为发生了太多我不需要也不理解的事情。

我确实理解为什么人们想要ax 的所有强大选项,但我不明白为什么熊猫绘图功能中不包含这样一个简单的选项。而且似乎我不是唯一一个。例如,用户 Chrispy 发布了这条高度评价的评论:

x 和 y 标签不能作为参数添加到pd.plot() 有什么特殊原因吗?考虑到pd.plot()plt.plot() 更加简洁,看起来更简洁而不是调用ax.set_ylabel() 似乎是有意义的

关于this question 的答案,但没有进一步的 cmets。因此,我公然窃取这个问题。

为什么plt.plot()默认包含图例,也很容易让我添加标题(my_df.plot(title = 'check out my cool plot')),但合乎逻辑的下一步(my_df.plot(ylabel = 'size in meters'))会导致TypeError: There is no Line2D property "ylabel"

是我遗漏了什么还是有这个疏忽的原因?

示例代码:

当我在我的真实文件中实现它并在 ipython 中使用run workflow.py 运行它时,这可以工作,但是在复制粘贴代码时我无法重现它。我的标签要么被忽略,要么彻底失败:

编辑:

最初我在这里的示例中有plt.xlabel = 'time in seconds',但它不起作用,但我在实际代码中使用了正确的plt.xlabel('time in seconds'),这当然起作用了。

times = np.arange(0,43200,60)
my_df = pd.DataFrame(np.random.randn(len(times)), index = times)
my_df.plot(title = 'just some random data')    #this works
#my_df.plot(title = 'just some random data', ylabel = 'size in meters', xlabel = 'time in seconds')    #this seems like the logical next step, but it errors
plt.ylabel('size in meters')
plt.xlabel('time in seconds')

这似乎是axes 最简单/最小的解决方案,使用@Johannes 解决方案,但我认为这(参见 cmets 的答案)也是一个很好的说明,为什么我不想用 @ 来打扰自己987654341@:

axes = my_df.plot(title = 'just some random data')
axes.set_ylabel('size in meters')
axes.set_xlabel('time in seconds')

另外,我可以用另一种方式设置标题,但标签只有一个选项,这让我感到困惑:

axes = my_df.plot()
axes.set_title('just some random data')
axes.set_ylabel('size in meters')
axes.set_xlabel('time in seconds')

【问题讨论】:

【参考方案1】:

首先,pandas 绘图命令没有特别的理由不包括标签的关键字参数,就像标题一样。 这个选项可以很好地实现,但不是。推测原因不会有任何结果,但pandas issue tracker 有一个问题。

关于实际问题,有几种方法可以为轴设置标签。下面列出了三种可能的方法。请注意,在问题以及其他答案中,出现了一些无效的方法。

尤其是ax.xlabel() 不存在。 plt.ylabel = 'size in meters' 也没有任何意义,因为它覆盖 ylabel 方法而不是使用它。

工作选项:

ax.set_xlabel()

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

times = np.arange(0,43200,60)
my_df = pd.DataFrame(np.random.randn(len(times)), index = times)
ax = my_df.plot(title = 'just some random data')

ax.set_ylabel('size in meters')
ax.set_xlabel('time in seconds')

plt.show()

ax.set()

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

times = np.arange(0,43200,60)
my_df = pd.DataFrame(np.random.randn(len(times)), index = times)
ax = my_df.plot(title = 'just some random data')
ax.set(xlabel='time in seconds', ylabel='size in meters')

plt.show()

plt.xlabel()

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

times = np.arange(0,43200,60)
my_df = pd.DataFrame(np.random.randn(len(times)), index = times)
my_df.plot(title = 'just some random data')

plt.ylabel('size in meters')
plt.xlabel('time in seconds')

plt.show()

plt.setp()

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

times = np.arange(0,43200,60)
my_df = pd.DataFrame(np.random.randn(len(times)), index = times)
ax = my_df.plot(title = 'just some random data')

plt.setp(ax,xlabel='time in seconds', ylabel='size in meters')

plt.show()

【讨论】:

我明白了。我想可能有一个原因,我只是忽略了,但似乎没有。如果我能找到时间和我的登录数据,也许我会在 github 上建议它。 plt.ylabel = 'size in meters' 可能是在我的真实剧本和 MWE 之间来回走动时偷偷溜进来的,因为我一开始就提出了这个问题。 如您所见here 这不是新问题。 如果您正在绘制熊猫系列,plt.setp() 可以工作【参考方案2】:

df.plot() 返回Axes 对象的列表(每个子图一个)。那些有.set_xlabel().set_ylabel() 方法。

做这样的事情:

times = np.arange(0,43200,60)
my_df = pd.DataFrame(np.random.randn(len(times)), index = times)
axes = my_df.plot(title = 'just some random data')
axes[0].ylabel('size in meters')
axes[0].xlabel('time in seconds')

绘图不是对象,plot 函数只是创建 Line 对象。由于您可以在单个 Axes 对象中包含多条线,但只有一对标签,因此标签是轴的属性而不是线的属性是有意义的。

【讨论】:

但是我不能也有多个标签(例如辅助 y 轴)吗?而且我无论如何也不能设置多个标题,那么为什么不也允许我以这种方式设置标签呢?你的例子对我来说以TypeError: 'AxesSubplot' object does not support indexing 结尾。不应该是axes.set_ylabel =...吗?而且我也可以使用axes.set_title=...,因此假设pd.plot() 的行为也相同是合乎逻辑的 您可以有多个 y 轴,但不能超过两个,并且它作为一种特殊情况实现。当只有一个子图时,看起来plot 返回单个 Axes 对象而不是一个元素列表。尝试省略 [0] 并直接使用 axes.ylabel('size in meters') 等。 省略 [0] 只是不绘制任何内容。 axes.set_ylabel = 'size in meters' 确实有效。

以上是关于为啥我不能将 x 和 y 标签设置为 pd.plot() 的参数,而我可以轻松设置类似的东西,例如标题?的主要内容,如果未能解决你的问题,请参考以下文章

简单的 Python 问题:为啥我不能将变量分配给排序列表(就地)? [复制]

Matplotlib。设置标题一个x和y标签[重复]

将 y 轴标签的位置更改为 windows 窗体图表的底部

为啥 return 0 或 break 不能与逗号运算符一起使用?

Matplotlib 在所有子图上显示 x-ticks 和唯一的 y 标签

matlab - 在原点设置刻度标签