首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Python的pandas中从数据帧制作matplotlib散点图

在Python的pandas中从数据帧制作matplotlib散点图
EN

Stack Overflow用户
提问于 2013-01-13 10:38:30
回答 3查看 139.5K关注 0票数 86

在Python语言中使用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])

在绘图之前将所有内容转换为数组的问题是,它会迫使您中断数据帧。

考虑以下两个用例,在这些用例中,拥有完整的数据帧对于绘图至关重要:

  1. 例如,如果您现在想要查看col3的所有值,以获得您在调用scatter时绘制的相应值,并根据该值对每个点(或大小)进行着色,该怎么办?您必须返回,取出col1,col2的非na值,并检查它们的相应值。

有没有一种方法可以在保存数据帧的同时进行绘图?例如:

mydata = df.dropna(how="any",subset=" col1 "," col2 ") #绘制col1 by col2的散点,大小根据col3散布(mydata(“col1”,"col2") ),假设您想要根据某些列的值对每个点进行不同的过滤或着色。例如,如果您想要在col1, col2上自动绘制满足特定截止点的点的标签(标签存储在df的另一列中),或者对这些点进行不同的着色,就像人们在R中处理数据帧一样。例如:

mydata = df.dropna(how="any",subset="col1"," col2 ") myscatter = scatter(mydata["col1","col2"],s=1) #用红色绘制,尺寸较小,所有col2值大于0.5的点myscatter.replot(mydata"col2“> 0.5,color=" red ",s=0.5)

如何做到这一点?

编辑回复给crewbum:

您说最好的方法是分别绘制每个条件(如subset_asubset_b)。如果你有很多条件,比如你想把散点分成4种类型的点,甚至更多,用不同的形状/颜色绘制每个点该怎么办?如何优雅地应用条件a、b、c等,并确保将“其余部分”(不在这些条件中的内容)绘制为最后一步?

类似地,在您的示例中,您根据col3绘制不同的col1,col2,如果有NA值打破了col1,col2,col3之间的关联,该怎么办?例如,如果您希望根据其col3值绘制所有col2值,但某些行在col1col3中具有安娜值,则强制您首先使用dropna。所以你会这样做:

mydata = df.dropna(how="any", subset=["col1", "col2", "col3")

然后,您可以像您所展示的那样使用mydata绘制--使用col3的值绘制col1,col2之间的散点。但是mydata会遗漏一些点,这些点具有col1,col2的值,但对于col3来说是NA,这些点仍然需要绘制...那么,基本上如何绘制数据的“其余部分”,即不在过滤集合mydata中的点

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-14 02:48:58

尝试将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)

带有图例的散点图

但是,我发现创建带有图例的散点图的最简单方法是为每个点类型调用一次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样式设置(例如,颜色/大小)的点。要查找由于NA而跳过的点,请尝试使用isnull方法:df[df.col3.isnull()]

要将一组点拆分为多个类型,请看一下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()

票数 119
EN

Stack Overflow用户

发布于 2017-10-15 18:28:44

Garrett的回答很棒,没有什么可补充的,但熊猫也有一个scatter method。使用它,它就像

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'])

票数 7
EN

Stack Overflow用户

发布于 2019-06-23 18:55:37

我建议使用另一种方法,使用seaborn,这是一种功能更强大的数据绘图工具。您可以使用seaborn scatterplot并将第3列定义为huesize

工作代码:

import pandas as pd
import seaborn as sns
import numpy as np

#creating sample data 
sample_data={'col_name_1':np.random.rand(20),
      'col_name_2': np.random.rand(20),'col_name_3': np.arange(20)*100}
df= pd.DataFrame(sample_data)
sns.scatterplot(x="col_name_1", y="col_name_2", data=df, hue="col_name_3",size="col_name_3")

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14300137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档