天天看點

Pandas進階教程之:plot畫圖詳解簡介基礎畫圖其他圖像在畫圖中處理NaN資料其他作圖工具圖像的格式

簡介

python中matplotlib是非常重要并且友善的圖形化工具,使用matplotlib可以可視化的進行資料分析,今天本文将會詳細講解Pandas中的matplotlib應用。

基礎畫圖

要想使用matplotlib,我們需要引用它:

In [1]: import matplotlib.pyplot as plt      

假如我們要從2020年1月1日開始,随機生成365天的資料,然後作圖表示應該這樣寫:

ts = pd.Series(np.random.randn(365), index=pd.date_range("1/1/2020", periods=365))
ts.plot()      

使用DF可以同時畫多個Series的圖像:

df3 =  pd.DataFrame(np.random.randn(365, 4), index=ts.index, columns=list("ABCD"))
 df3= df3.cumsum()
df3.plot()      

可以指定行和列使用的資料:

df3 = pd.DataFrame(np.random.randn(365, 2), columns=["B", "C"]).cumsum()
df3["A"] = pd.Series(list(range(len(df))))
df3.plot(x="A", y="B");      

其他圖像

plot() 支援很多圖像類型,包括bar, hist, box, density, area, scatter, hexbin, pie等,下面我們分别舉例子來看下怎麼使用。

bar

df.iloc[5].plot(kind="bar");      

多個列的bar:

df2 = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])
df2.plot.bar();      

stacked bar

df2.plot.bar(stacked=True);      

barh

barh 表示橫向的bar圖:

df2.plot.barh(stacked=True);      

Histograms

df2.plot.hist(alpha=0.5);      

box

df.plot.box();      

box可以自定義顔色:

color = {
   ....:     "boxes": "DarkGreen",
   ....:     "whiskers": "DarkOrange",
   ....:     "medians": "DarkBlue",
   ....:     "caps": "Gray",
   ....: }
df.plot.box(color=color, sym="r+");      

可以轉成橫向的:

df.plot.box(vert=False);      

除了box,還可以使用DataFrame.boxplot來畫box圖:

In [42]: df = pd.DataFrame(np.random.rand(10, 5))
In [44]: bp = df.boxplot()      

boxplot可以使用by來進行分組:

df = pd.DataFrame(np.random.rand(10, 2), columns=["Col1", "Col2"])
df
Out[90]: 
       Col1      Col2
0  0.047633  0.150047
1  0.296385  0.212826
2  0.562141  0.136243
3  0.997786  0.224560
4  0.585457  0.178914
5  0.551201  0.867102
6  0.740142  0.003872
7  0.959130  0.581506
8  0.114489  0.534242
9  0.042882  0.314845
df.boxplot()      

現在給df加一列:

df["X"] = pd.Series(["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"])
df
Out[92]: 
       Col1      Col2  X
0  0.047633  0.150047  A
1  0.296385  0.212826  A
2  0.562141  0.136243  A
3  0.997786  0.224560  A
4  0.585457  0.178914  A
5  0.551201  0.867102  B
6  0.740142  0.003872  B
7  0.959130  0.581506  B
8  0.114489  0.534242  B
9  0.042882  0.314845  B
bp = df.boxplot(by="X")      

Area

使用 Series.plot.area() 或者 DataFrame.plot.area() 可以畫出area圖。

In [60]: df = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])
In [61]: df.plot.area();      

如果不想疊加,可以指定stacked=False

In [62]: df.plot.area(stacked=False);      

Scatter

DataFrame.plot.scatter() 可以建立點圖。

In [63]: df = pd.DataFrame(np.random.rand(50, 4), columns=["a", "b", "c", "d"])
In [64]: df.plot.scatter(x="a", y="b");      

scatter圖還可以帶第三個軸:

df.plot.scatter(x="a", y="b", c="c", s=50);      

可以将第三個參數變為散點的大小:

df.plot.scatter(x="a", y="b", s=df["c"] * 200);      

Hexagonal bin

使用 DataFrame.plot.hexbin() 可以建立蜂窩圖:

In [69]: df = pd.DataFrame(np.random.randn(1000, 2), columns=["a", "b"])
In [70]: df["b"] = df["b"] + np.arange(1000)
In [71]: df.plot.hexbin(x="a", y="b", gridsize=25);      

預設情況下顔色深度表示的是(x,y)中元素的個數,可以通過reduce_C_function來指定不同的聚合方法:比如

mean

,

max

sum

std

.

In [72]: df = pd.DataFrame(np.random.randn(1000, 2), columns=["a", "b"])
In [73]: df["b"] = df["b"] = df["b"] + np.arange(1000)
In [74]: df["z"] = np.random.uniform(0, 3, 1000)
In [75]: df.plot.hexbin(x="a", y="b", C="z", reduce_C_function=np.max, gridsize=25);      

Pie

使用 DataFrame.plot.pie() 或者 Series.plot.pie()來建構餅圖:

In [76]: series = pd.Series(3 * np.random.rand(4), index=["a", "b", "c", "d"], name="series")
In [77]: series.plot.pie(figsize=(6, 6));      

可以按照列的個數分别作圖:

In [78]: df = pd.DataFrame(
   ....:     3 * np.random.rand(4, 2), index=["a", "b", "c", "d"], columns=["x", "y"]
   ....: )
   ....: 
In [79]: df.plot.pie(subplots=True, figsize=(8, 4));      

更多定制化的内容:

In [80]: series.plot.pie(
   ....:     labels=["AA", "BB", "CC", "DD"],
   ....:     colors=["r", "g", "b", "c"],
   ....:     autopct="%.2f",
   ....:     fontsize=20,
   ....:     figsize=(6, 6),
   ....: );      

如果傳入的value值加起來不是1,那麼會畫出一個傘形:

In [81]: series = pd.Series([0.1] * 4, index=["a", "b", "c", "d"], name="series2")
In [82]: series.plot.pie(figsize=(6, 6));      

在畫圖中處理NaN資料

下面是預設畫圖方式中處理NaN資料的方式:

畫圖方式 處理NaN的方式
Line Leave gaps at NaNs
Line (stacked) Fill 0’s
Bar
Drop NaNs
Histogram Drop NaNs (column-wise)
Box
KDE
Hexbin

其他作圖工具

散點矩陣圖Scatter matrix

可以使用pandas.plotting中的scatter_matrix來畫散點矩陣圖:

In [83]: from pandas.plotting import scatter_matrix
In [84]: df = pd.DataFrame(np.random.randn(1000, 4), columns=["a", "b", "c", "d"])
In [85]: scatter_matrix(df, alpha=0.2, figsize=(6, 6), diagonal="kde");      

密度圖Density plot

使用 Series.plot.kde() 和 DataFrame.plot.kde() 可以畫出密度圖:

In [86]: ser = pd.Series(np.random.randn(1000))
In [87]: ser.plot.kde();      

安德魯斯曲線Andrews curves

安德魯斯曲線允許将多中繼資料繪制為大量曲線,這些曲線是使用樣本的屬性作為傅裡葉級數的系數建立的. 通過為每個類對這些曲線進行不同的着色,可以可視化資料聚類。 屬于同一類别的樣本的曲線通常會更靠近在一起并形成較大的結構。

In [88]: from pandas.plotting import andrews_curves
In [89]: data = pd.read_csv("data/iris.data")
In [90]: plt.figure();
In [91]: andrews_curves(data, "Name");      

平行坐标Parallel coordinates

平行坐标是一種用于繪制多中繼資料的繪制技術。 平行坐标允許人們檢視資料中的聚類,并直覺地估計其他統計資訊。 使用平行坐标點表示為連接配接的線段。 每條垂直線代表一個屬性。 一組連接配接的線段代表一個資料點。 趨于聚集的點将顯得更靠近。

In [92]: from pandas.plotting import parallel_coordinates
In [93]: data = pd.read_csv("data/iris.data")
In [94]: plt.figure();
In [95]: parallel_coordinates(data, "Name");      

滞後圖lag plot

滞後圖是用時間序列和相應的滞後階數序列做出的散點圖。可以用于觀測自相關性。

In [96]: from pandas.plotting import lag_plot
In [97]: plt.figure();
In [98]: spacing = np.linspace(-99 * np.pi, 99 * np.pi, num=1000)
In [99]: data = pd.Series(0.1 * np.random.rand(1000) + 0.9 * np.sin(spacing))
In [100]: lag_plot(data);      

自相關圖Autocorrelation plot

自相關圖通常用于檢查時間序列中的随機性。 自相關圖是一個平面二維坐标懸垂線圖。橫坐标表示延遲階數,縱坐标表示自相關系數。

In [101]: from pandas.plotting import autocorrelation_plot
In [102]: plt.figure();
In [103]: spacing = np.linspace(-9 * np.pi, 9 * np.pi, num=1000)
In [104]: data = pd.Series(0.7 * np.random.rand(1000) + 0.3 * np.sin(spacing))
In [105]: autocorrelation_plot(data);      

Bootstrap plot

bootstrap plot用于直覺地評估統計資料的不确定性,例如均值,中位數,中間範圍等。從資料集中選擇指定大小的随機子集,為該子集計算出相關統計資訊, 重複指定的次數。 生成的圖和直方圖構成了引導圖。

In [106]: from pandas.plotting import bootstrap_plot
In [107]: data = pd.Series(np.random.rand(1000))
In [108]: bootstrap_plot(data, size=50, samples=500, color="grey");      

RadViz

他是基于彈簧張力最小化算法。它把資料集的特征映射成二維目标空間機關圓中的一個點,點的位置由系在點上的特征決定。把執行個體投入圓的中心,特征會朝圓中此執行個體位置(執行個體對應的歸一化數值)“拉”執行個體。

In [109]: from pandas.plotting import radviz
In [110]: data = pd.read_csv("data/iris.data")
In [111]: plt.figure();
In [112]: radviz(data, "Name");      

圖像的格式

matplotlib 1.5版本之後,提供了很多預設的畫圖設定,可以通過matplotlib.style.use(my_plot_style)來進行設定。

可以通過使用matplotlib.style.available來列出所有可用的style類型:

import matplotlib as plt;
plt.style.available
Out[128]: 
['seaborn-dark',
 'seaborn-darkgrid',
 'seaborn-ticks',
 'fivethirtyeight',
 'seaborn-whitegrid',
 'classic',
 '_classic_test',
 'fast',
 'seaborn-talk',
 'seaborn-dark-palette',
 'seaborn-bright',
 'seaborn-pastel',
 'grayscale',
 'seaborn-notebook',
 'ggplot',
 'seaborn-colorblind',
 'seaborn-muted',
 'seaborn',
 'Solarize_Light2',
 'seaborn-paper',
 'bmh',
 'seaborn-white',
 'dark_background',
 'seaborn-poster',
 'seaborn-deep']      

去掉小圖示

預設情況下畫出來的圖會有一個表示列類型的圖示,可以使用legend=False禁用:

In [115]: df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD"))
In [116]: df = df.cumsum()
In [117]: df.plot(legend=False);      

設定label的名字

In [118]: df.plot();
In [119]: df.plot(xlabel="new x", ylabel="new y");      

縮放

畫圖中如果X軸或者Y軸的資料差異過大,可能會導緻圖像展示不友好,數值小的部分基本上無法展示,可以傳入logy=True進行Y軸的縮放:

In [120]: ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))
In [121]: ts = np.exp(ts.cumsum())
In [122]: ts.plot(logy=True);      

多個Y軸

使用secondary_y=True 可以繪制多個Y軸資料:

In [125]: plt.figure();
In [126]: ax = df.plot(secondary_y=["A", "B"])
In [127]: ax.set_ylabel("CD scale");
In [128]: ax.right_ax.set_ylabel("AB scale");      

小圖示上面預設會添加right字樣,想要去掉的話可以設定mark_right=False:

In [129]: plt.figure();
In [130]: df.plot(secondary_y=["A", "B"], mark_right=False);      

坐标文字調整

使用時間做坐标的時候,因為時間太長,導緻x軸的坐标值顯示不完整,可以使用x_compat=True 來進行調整:

In [133]: plt.figure();
In [134]: df["A"].plot(x_compat=True);      

如果有多個圖像需要調整,可以使用with:

In [135]: plt.figure();
In [136]: with pd.plotting.plot_params.use("x_compat", True):
   .....:     df["A"].plot(color="r")
   .....:     df["B"].plot(color="g")
   .....:     df["C"].plot(color="b")
   .....:      

子圖

繪制DF的時候,可以将多個Series分開作為子圖顯示:

In [137]: df.plot(subplots=True, figsize=(6, 6));      

可以修改子圖的layout:

df.plot(subplots=True, layout=(2, 3), figsize=(6, 6), sharex=False);      

上面等價于:

In [139]: df.plot(subplots=True, layout=(2, -1), figsize=(6, 6), sharex=False);      

一個更複雜的例子:

In [140]: fig, axes = plt.subplots(4, 4, figsize=(9, 9))
In [141]: plt.subplots_adjust(wspace=0.5, hspace=0.5)
In [142]: target1 = [axes[0][0], axes[1][1], axes[2][2], axes[3][3]]
In [143]: target2 = [axes[3][0], axes[2][1], axes[1][2], axes[0][3]]
In [144]: df.plot(subplots=True, ax=target1, legend=False, sharex=False, sharey=False);
In [145]: (-df).plot(subplots=True, ax=target2, legend=False, sharex=False, sharey=False);      

畫表格

如果設定table=True , 可以直接将表格資料一并顯示在圖中:

In [165]: fig, ax = plt.subplots(1, 1, figsize=(7, 6.5))
In [166]: df = pd.DataFrame(np.random.rand(5, 3), columns=["a", "b", "c"])
In [167]: ax.xaxis.tick_top()  # Display x-axis ticks on top.
In [168]: df.plot(table=True, ax=ax)
fig      

table還可以顯示在圖檔上面:

In [172]: from pandas.plotting import table
In [173]: fig, ax = plt.subplots(1, 1)
In [174]: table(ax, np.round(df.describe(), 2), loc="upper right", colWidths=[0.2, 0.2, 0.2]);
In [175]: df.plot(ax=ax, ylim=(0, 2), legend=None);      

使用Colormaps

如果Y軸的資料太多的話,使用預設的線的顔色可能不好分辨。這種情況下可以傳入colormap 。

In [176]: df = pd.DataFrame(np.random.randn(1000, 10), index=ts.index)
In [177]: df = df.cumsum()
In [178]: plt.figure();
In [179]: df.plot(colormap="cubehelix");      
本文已收錄于 http://www.flydean.com/09-python-pandas-plot/ 最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!