【问题标题】:inconsistency between DataFrame.plot.scatter and DataFrame.plot.density()?DataFrame.plot.scatter 和 DataFrame.plot.density() 之间不一致?
【发布时间】:2018-08-08 04:04:38
【问题描述】:

以下示例说明了 pandas DataFrame 的散点图和密度图之间的奇怪差异 .. 或者可能是我缺乏理解:

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

n = 25
df = pd.DataFrame({'x': np.random.randn(n), 'y': np.random.randn(n), 'season': np.random.choice(['winter', 'summer'], n)})

plot = df.plot.scatter(x='x', y='y')
plot.get_figure().savefig("test_scatter_all.png")
for s in ['winter', 'summer']:
    sdf = df[df['season'] == s]
    plot = sdf.plot.scatter(x='x', y='y')
    plot.get_figure().savefig("test_scatter_" + s + ".png")

plt.clf()

plot = df['y'].plot.density()
plot.get_figure().savefig("test_density_all.png")
for s in ['winter', 'summer']:
    sdf = df[df['season'] == s]
    plot = sdf['y'].plot.density()
    plot.get_figure().savefig("test_density_" + s + ".png")

让我感到惊讶的是,密度图是相加的,因为冬季图表包括两个密度(“全部”和冬季),而夏季图表包括所有三个密度。 另一方面,散点图仅包含它们自己的点,即冬季图中的冬季值等。
此外,如果没有 plt.clf() 命令,密度图还将包括上一个散点图(夏季)的点。

为什么两种绘图类型之间存在差异? 这是否意味着在开始新情节之前我应该​​始终使用plt.clf()

顺便说一句,像我这样使用plot 对象真的有意义吗?我看到我可以用

生成第一个图
df.plot.scatter(x='x', y='y')
plt.savefig("test_scatter_all.png")

那么,捕获plot() 方法的输出有什么意义吗?这是否意味着plot() 方法写入的活动图形对象始终只有一个?

【问题讨论】:

    标签: python pandas matplotlib plot


    【解决方案1】:

    不一致的不是密度和散点,而是dataframe的绘制方式和series的绘制方式:

    • 一个系列,Series.plot,被绘制到活动轴上,如果有,则创建一个新图形。

    • 一个数据框 DataFrame.plot 被绘制到一个新图上,与是否已经存在无关。

    例子:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.DataFrame({'x': np.random.randn(25), 'y': np.random.randn(25), 
                       'season': np.random.choice(['red', 'gold'], 25)})
    
    # This plots the dataframe, and creates two figures
    for s in ['red', 'gold']:
        sdf = df[df['season'] == s]
        plot = sdf.plot(kind="line",color=s)
    plt.show() 
    
    # This plots a series, and creates a single figure  
    for s in ['red', 'gold']:
        sdf = df[df['season'] == s]
        plot = sdf["y"].plot(kind="line",color=s)
    plt.show()
    

    这里,sdf.plot 创建了两个图形,而 sdf["y"].plot 绘制到相同的轴。


    如果问题是要在图中保留先前绘制的密度,您可以绘制此密度,添加另一个密度,保存图形并最后删除第二个图,这样您就可以得到第一个密度图,准备绘制其他内容给它。
    import numpy as np
    import pandas as pd
    
    df = pd.DataFrame({'x': np.random.randn(25), 'y': np.random.randn(25), 
                       'season': np.random.choice(['red', 'gold'], 25)})
    
    ax = df['y'].plot.density()
    for s in ['red', 'gold']:
        sdf = df[df['season'] == s]
        sdf["y"].plot.density(color=s)
        ax.get_figure().savefig("test_density_" + s + ".png")
        ax.lines[-1].remove()
    

    【讨论】:

    • 我不确定哪种情况适合您。但是,如果您想指定所需的输出应该是什么,肯定有一个解决方案,我可以将其添加到答案中。
    • 谢谢,这是有道理的。如果我想要每个季节的密度图包括两条线:总密度 + 季节密度。有没有办法存储和重复使用整体密度图,所以它只计算一次?
    • 对于密度,这应该是默认行为,因为您绘制了一个系列,因此该图将添加到任何先前存在的图中。
    • 是的,但是如果我先绘制整体密度,然后添加冬季密度,我该如何创建春季图表,我只需要整体密度和春季密度?而且我不想再次进行整体密度估计..
    • 我没有看到两次绘制密度的问题。这一步是否花费了太多时间,或者不想这样做的原因是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 2015-03-10
    • 2013-11-17
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多