以下示例说明了来自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()
方法始终只有一个活动的图形对象写入?
答案 0 :(得分:1)
不一致不是在密度和散射之间,而是在数据框的绘图方法和系列的绘图方法之间:
系列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()