program tip

Python 팬더의 데이터 프레임에서 matplotlib 산점도 만들기

radiobox 2020. 11. 15. 11:06
반응형

Python 팬더의 데이터 프레임에서 matplotlib 산점도 만들기


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)
    

어떻게 할 수 있습니까?

crewbum에 대한 답변 수정 :

가장 좋은 방법은 각 조건 (예 : subset_a, subset_b)을 개별적 으로 플로팅하는 것 입니다. 여러 조건이있는 경우, 예를 들어 산포를 4 가지 유형의 점 또는 그 이상으로 분할하여 각각 다른 모양 / 색상으로 플로팅하려는 경우 어떻게해야합니까? 조건 a, b, c 등을 우아하게 적용하고 마지막 단계로 "나머지"(이러한 조건에 속하지 않는 것)를 플로팅하는 방법은 무엇입니까?

col1,col2기반으로 다르게 플롯하는 예제에서 유사하게 col3, 사이의 연관성을 끊는 NA 값이 있으면 col1,col2,col3어떻게 될까요? 예를 들어, 당신은 모든 플롯하려면 col2자신의에 따라 값 col3값을하지만, 일부 행은 하나의 NA 값이 col1또는 col3사용하도록 강제 dropna첫째. 따라서 다음을 수행합니다.

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

그런 다음 mydata표시 하는 것처럼 플롯 할 수 있습니다 . col1,col2값을 사용하여 분산을 플로팅합니다 col3. 그러나에 mydata대한 값이 col1,col2있지만 NA 인 일부 포인트가 누락 col3되고 여전히 플로팅해야합니다. 따라서 기본적으로 데이터의 "나머지", 즉 필터링 된 세트에 없는 포인트를 어떻게 플로팅 mydata할까요?


열을 DataFramenumpy 배열로 추출하는 대신 아래 예제와 같이 matplotlib에 직접 전달해 보십시오 .

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()

여기에 이미지 설명 입력

최신 정보

From what I can tell, matplotlib simply skips points with NA x/y coordinates or NA style settings (e.g., color/size). To find points skipped due to NA, try the isnull method: df[df.col3.isnull()]

To split a list of points into many types, take a look at numpy select, which is a vectorized if-then-else implementation and accepts an optional default value. For example:

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()

여기에 이미지 설명 입력


There is little to be added to Garrett's great answer, but pandas also has a scatter method. Using that, it's as easy as

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로 크기 플로팅


I will recommend to use an alternative method using seaborn which more powerful tool for data plotting. You can use seaborn scatterplot and define colum 3 as hue and size.

Working code:

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")

여기에 이미지 설명 입력

참고 URL : https://stackoverflow.com/questions/14300137/making-matplotlib-scatter-plots-from-dataframes-in-pythons-pandas

반응형