【问题标题】: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')

【问题讨论】:

    标签: python pandas matplotlib plot


    【解决方案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' 确实有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 2011-06-19
    相关资源
    最近更新 更多