根据Python大熊猫中的数据框制作matplotlib散点图


77

使用Python中matplotlibpandas数据框制作一系列散点图的最佳方法是什么?

例如,如果我的数据框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,并用该值为每个点(或大小)上色,该怎么办?您必须返回,拉出的非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"])
    
  2. 同样,假设您要根据每个点的某些列的值对每个点进行不同的过滤或着色。例如,如果您要自动在其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_asubset_b)分开。如果您有许多条件,例如要将散布分为4种或更多类型的点,并以不同的形状/颜色进行绘制,该怎么办?您如何优雅地应用条件a,b,c等,并确保随后绘制“其余”(这些条件中未包含的任何内容)作为最后一步?

类似地,在示例中,您col1,col2根据进行col3了不同的绘制,如果存在破坏两者之间关联的NA值col1,col2,col3怎么办?例如,如果你想绘制所有col2基于自己的价值观col3价值,但某些行有任何的NA值col1col3会迫使用户使用dropna第一。所以你会做:

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

那么您可以如图所示使用mydata-绘制col1,col2使用的值之间的散点图col3。但是mydata会丢失一些具有的值col1,col2但为的值为NA的点col3,而这些点仍必须绘制...所以您基本上将如何绘制数据的“其余”,即不在过滤集中的点mydata


2
同时情况有所变化,请参阅官方文档中的“绘图-绘图-散点图”
Piotr Migdal

Answers:


114

尝试将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样式设置(例如颜色/大小)的点。若要查找由于不适用而跳过的点,请尝试以下isnull方法:df[df.col3.isnull()]

要将点列表分为多种类型,请看一下numpyselect,它是向量化的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()

在此处输入图片说明


1
好答案!我不知道这些。我通常将数据转换成我喜欢的格式,然后将其发送到R进行ggplot。这些示例将使我在pandas / python中做更多工作-谢谢。
zach 2013年

如何在图例中制作具有特定大小的单个圆?
nbsrujan

6

加勒特(Garrett)的绝妙回答几乎没有增加,但熊猫也有一种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'])

在col3到col1-col2中绘制大小


3

我将建议使用另一种方法,使用seaborn该方法可以使用功能更强大的数据绘图工具。您可以使用seaborn scatterplotcolum 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")

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.