两个图表,两个坐标轴,一个图形……卡住了。

3
我正在尝试从数据集中绘制两个不同x和y范围的图形。我对plt.figure、plt.subplot和plt.axes之间的交互感到困惑。
假设我要绘制代表不同特征(用字母A-G表示的贷款)的值("ROI")的线,对于不同的贷款期限('term'),'发行日期'的范围是不同的(例如,对于36个月的期限,自2007年以来已经发放了贷款,而对于60个月的期限,仅自2011年以来才开始发放贷款)。
以下是我所拥有的伪代码。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from itertools import groupby

alpha_grades = ('A','B','C','D','E','F','G')

color_scheme = {'A':'b','B':'g','C':'r','D':'c','E':'m','F':'y','G':'k'}

for term in [36,60]:
    for grade in alpha_grades:
        if ( term == 36 ):
            plt.figure(1,figsize=(12,9))
        else:
            plt.figure(2,figsize=(12,9))

    df[(df['grade'] == grade) & (df['term']==term)].groupby(
        'issue_date')['ROI'].mean().plot(color=color_scheme[grade],label = ("Grade: %s" % grade))
    plt.legend(loc=2)
    title = ("%i Mo Lending Rate by Rating" % term)
    plt.title(title)

这个版本的屏幕和文件输出中,第一个图表(term == 36)的大小比第二个小得多。我想通过定义两个具有相同尺寸的单独图形来解决这个问题,您觉得可行吗?感谢您提前的帮助!

当您调用plt.figure时,它会创建一个新的图形。更可能的是,您想要调用plt.subplot。第一次调用应该像这样:plt.subplot(1, 2, 1),第二次调用应该是plt.subplot(1, 2, 2)(参数为:nrows,ncols,plot_number)。 - askewchan
@askewchan - 谢谢,我之前尝试过并且效果更好,但是图表使用了相同的X轴。不确定如何解决这个问题。我发现MATPLOTLIB非常令人困惑。 - GPB
哈哈,是的,matplotlib确实非常令人困惑,但就我所知,在Python中它是最好的。如果您可以创建一个不依赖于数据的示例(您可以随机生成),那么人们可以提供更多帮助。目前,我不太确定您所说的“相同X轴”是什么意思。 - askewchan
@askewchan - 谢谢。我所说的“相同的X轴”是指绘制在彼此上方的图形,只有底部的图形有标记的轴,用于拟合两个系列。对我来说很难制作一个随机数据集,但如果我告诉你x轴是一系列日期(格式为MMYYYY),而期限值= 36的日期从2007年至2012年,而期限值= 60的日期从2010年至2012年,这会有帮助吗?对于新手来说,很难快速发明一个说明这个问题的数据集! - GPB
1个回答

3

图形基本上就是一个窗口。该窗口可以有一个或多个坐标轴,每个坐标轴都是一个绘图。 plt.subplot 允许您在一个图中创建多个坐标轴。图形和坐标轴都是对象,具有自己的方法。例如,plt.plot 只是一个围绕一个 axes 对象的 plot 方法的简单包装器。

在您的情况下,您不想直接调用其中任何一个。相反,您应该调用 plt.subplots()(注意末尾的“s”)。这是一个方便的函数,它将创建一个图形,在该图形中放置一个或多个坐标轴,并返回图形和所有坐标轴。然后,您可以将坐标轴传递给 pandas 的 plot 函数,以强制其在该坐标轴上绘图。您还可以为该坐标轴设置 legendtitle,但在 pandas 中执行此操作可能更容易。

因此,以下内容应该可以工作(我也简化了一些内容):

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from itertools import groupby

alpha_grades = ('A','B','C','D','E','F','G')

color_scheme = {'A':'b','B':'g','C':'r','D':'c','E':'m','F':'y','G':'k'}

fig1, ax1 = plt.subplots(figsize=(12,9)) # same as plt.subplots(1, 1)
fig2, ax2 = plt.subplots(figsize=(12,9))

for term, ax in zip([36,60], [ax1, ax2]):
    ax.hold(True)
    for grade, color in color_scheme.items():
        df2 = df[(df['grade'] == grade) & (df['term']==term)]
        df3 = groupby('issue_date')['ROI'].mean()
        df3.plot(ax=ax, color=color, 
                 label=("Grade: %s" % grade))
    ax.hold(False)
    ax.legend(loc=2)
    ax.set_title("%i Mo Lending Rate by Rating" % term)

fig1.show()
fig2.show()

请注意,您直接与图形和坐标轴交互,而不是使用plt。如果您想将两个图形放在一个图中,比如一个在左边,一个在右边,您可以这样做:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from itertools import groupby

alpha_grades = ('A','B','C','D','E','F','G')

color_scheme = {'A':'b','B':'g','C':'r','D':'c','E':'m','F':'y','G':'k'}

fig, axs = plt.subplots(1, 2, figsize=(12*2,9))  # creates two axes

for term, ax in zip([36,60], axs):
    ax.hold(True)
    for grade, color in color_scheme.items():
        df2 = df[(df['grade'] == grade) & (df['term']==term)]
        df3 = groupby('issue_date')['ROI'].mean()
        df3.plot(ax=ax, color=color, 
                 label=("Grade: %s" % grade))
    ax.hold(False)
    ax.legend(loc=2)
    ax.set_title("%i Mo Lending Rate by Rating" % term)

fig.show()

另外,我不确定为什么你使用了两个不同的dfs(df2,df3)进行编码?我确定在groupby命令中也缺少对df2的引用。我使用了我的原始代码行,应该是一样的,n'est ce que pas? - GPB
我想我已经弄清楚了(部分):在您的df3.plot调用中,我错过了“ax = ax”的赋值。仍然在ax.title行上出现错误-消息是:“'Text' object is not callable.” - GPB
是的。可以工作。谢谢。对于处理更多图形,有什么风格建议吗?例如,如果我想单独绘制每个“等级”的图形?例如,我会在显示器上放置小图形(例如9x9),并将较大的图形保存到文件中。我仍然不太确定如何使用坐标轴,以及如何创建循环并定义/调用不同的坐标轴... - GPB
如果这是您要寻找的内容,请将答案标记为正确。在样式上,我不会在单个图上有超过3x3个轴网格,我会绘制到单独的文件中。至于循环中的轴,请查看subplots文档。它创建一个(n, m)的numpy数组,其中包含与图中轴的形状相匹配的Axes对象。您可以像遍历其他任何numpy数组一样遍历它,并将单个Axes对象传递给pandas,或直接使用它绘图,例如ax.plot(x, y) - TheBlackCat
谢谢你的帮助。我会尝试一下。已将答案标记为正确。 - GPB
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接