使matplotlib从Python的pandas中的数据框分散绘图
在Python中使用matplotlib
从pandas
数据matplotlib
制作一系列散点图的最佳方法是什么?
例如,如果我有一个数据框df
有一些感兴趣的列,我发现自己通常转换所有的数组:
import matplotlib.pylab as plt # df is a DataFrame: fetch col1 and col2 # and drop na rows if any of the columns are NA mydata = df[["col1", "col2"]].dropna(how="any") # Now plot with matplotlib vals = mydata.values plt.scatter(vals[:, 0], vals[:, 1])
在绘图之前把所有东西都转换成数组的问题是,它迫使你摆脱数据框。
考虑以下两种使用情况,其中具有完整的数据框对绘图至关重要:
-
例如,如果您现在想要查看
col3
所有值,以查找在调用中绘制的相应值以scatter
,并按照该值对每个点(或大小)进行着色? 你必须回去,拉出col1,col2
的非na值col1,col2
并检查它们相应的值。有没有一种方法来绘制,同时保留数据框? 例如:
mydata = df.dropna(how="any", subset=["col1", "col2"]) # plot a scatter of col1 by col2, with sizes according to col3 scatter(mydata(["col1", "col2"]), s=mydata["col3"])
-
同样,假设您想根据某些列的值对每个点进行不同的过滤或着色。 例如,如果您想自动绘制在
col1, col2
旁边(标签存储在df的另一列中)的特定截断点的标签,或者对这些点进行不同的着色,就像人们使用数据框R.例如:mydata = df.dropna(how="any", subset=["col1", "col2"]) myscatter = scatter(mydata[["col1", "col2"]], s=1) # Plot in red, with smaller size, all the points that # have a col2 value greater than 0.5 myscatter.replot(mydata["col2"] > 0.5, color="red", s=0.5)
如何才能做到这一点?
编辑答复船员:
你说最好的方法是分别绘制每个条件(比如subset_a
, subset_b
)。 如果你有很多条件,例如你想把分散点分成4类或更多的点,用不同的形状/颜色来绘制。 你怎么能优雅地适用条件a,b,c等等,并确保你把最后一步“rest”(不在这些条件中的任何一个)作为最后一步?
类似地,在你绘制col1,col2
例子中col1,col2
基于col3
是不同的,如果有那些打破col1,col2,col3
之间关系的NA值呢? 例如,如果要基于col3
值绘制所有col2
值,但某些行在col1
或col3
值为NA,则必须先使用dropna
。 所以你会这样做:
mydata = df.dropna(how="any", subset=["col1", "col2", "col3")
那么你可以使用像你显示的mydata
绘图 – 使用col3
的值绘制col1,col2
之间的散点图。 但是, mydata
会遗漏一些有col1,col2
值的点,但是col3
却是NA,还有一些点必须被绘制出来……所以你如何基本上绘制数据的其余部分,即不是在过滤的设置mydata
?
尝试直接将DataFrame
matplotlib,如下面的示例中所示,而不是将它们作为numpy数组提取。
df = pd.DataFrame(np.random.randn(10,2), columns=['col1','col2']) df['col3'] = np.arange(len(df))**2 * 100 + 100 In [5]: df Out[5]: col1 col2 col3 0 -1.000075 -0.759910 100 1 0.510382 0.972615 200 2 1.872067 -0.731010 500 3 0.131612 1.075142 1000 4 1.497820 0.237024 1700
根据另一列改变散点大小
plt.scatter(df.col1, df.col2, s=df.col3) # OR (with pandas 0.13 and up) df.plot(kind='scatter', x='col1', y='col2', s=df.col3)
基于另一列改变散点颜色
colors = np.where(df.col3 > 300, 'r', 'k') plt.scatter(df.col1, df.col2, s=120, c=colors) # OR (with pandas 0.13 and up) df.plot(kind='scatter', x='col1', y='col2', s=120, c=colors)
与传说的散点图
不过,我发现用图例创build散点图最简单的方法是对每个点types调用plt.scatter
一次。
cond = df.col3 > 300 subset_a = df[cond].dropna() subset_b = df[~cond].dropna() plt.scatter(subset_a.col1, subset_a.col2, s=120, c='b', label='col3 > 300') plt.scatter(subset_b.col1, subset_b.col2, s=60, c='r', label='col3 <= 300') plt.legend()
更新
从我所知道的情况来看,matplotlib只是简单地跳过NA x / y坐标或NA样式设置(例如,颜色/大小)的点。 要find由于NA而跳过的点,请尝试使用isnull
方法: df[df.col3.isnull()]
要将点列表分成许多types,请查看numpy select
,这是一个向量化的if-then-else实现,并接受一个可选的默认值。 例如:
df['subset'] = np.select([df.col3 < 150, df.col3 < 400, df.col3 < 600], [0, 1, 2], -1) for color, label in zip('bgrm', [0, 1, 2, -1]): subset = df[df.subset == label] plt.scatter(subset.col1, subset.col2, s=120, c=color, label=str(label)) plt.legend()
加勒特的答案很less,但pandas也有scatter
方法 。 使用它,就像一样简单
df = pd.DataFrame(np.random.randn(10,2), columns=['col1','col2']) df['col3'] = np.arange(len(df))**2 * 100 + 100 df.plot.scatter('col1', 'col2', df['col3'])