【R和Python对比】matplotlib和ggplot(二)

首先py的画图都是
xx.plot(kind=’xx’)的形式

这个和R的ggplot后面的geom_xxx比较类似。

但是py弱在图形的整合,例如ggplot里面有个stat,可以直接很方便的进行count,identity等操作,而py的数据集需要喂好了给matplot,不过这样也倒是省时,因为py的groupby本来就不算很麻烦(和R的datatable差不多)。

下面进行柱状图的绘制:

iris.groupby('Species')['Sepal.Length'].sum().plot(kind='bar',
                                                   title='Bar',
                                                   color='k')

这个相当于R的geom_bar(stat=’count’)

需要首先groupby Species,然后加总Sepal.Length,最后画一个柱状图,Color=K 就是黑色,如图:

【R和Python对比】matplotlib和ggplot(二)_第1张图片

同样的,可以用均值加总:

iris.groupby('Species')['Sepal.Length'].mean().plot(kind='bar',
                                                   title='Bar-mean',
                                                   color='b')

【R和Python对比】matplotlib和ggplot(二)_第2张图片

当然可以放两个柱状图一起:

iris.groupby('Species')['Sepal.Length',
                        'Sepal.Width'].sum().plot(kind='bar',
                                                  title='combinebar',
                                                  color='by')

这个color就是b和y,中间也没有间隔,这个和R倒是不太一样;

【R和Python对比】matplotlib和ggplot(二)_第3张图片

当然,也可以都放上,并旋转坐标轴的标签:

iris.groupby('Species').sum().plot(kind='bar',
                                   title='Identitybar',
                                   rot=1)

【R和Python对比】matplotlib和ggplot(二)_第4张图片

其中的rot=1 ,就是旋转xtick

也可以堆叠:

iris.groupby('Species').sum().plot(kind='bar',
                                   title='Stackbar',
                                   stacked=True)

【R和Python对比】matplotlib和ggplot(二)_第5张图片

当然可以旋转成水平,通过kind=barh

iris.groupby('Species').sum().plot(kind='barh',
                                   title='h-bar',
                                   stacked=True)

【R和Python对比】matplotlib和ggplot(二)_第6张图片

然后如果是做百分比柱状图,首先柱状图这部分是帮不了了,只能求助于数据整形;

而数据整形的话,需要把三个种类,整成百分比的样子;这个略微有点技巧;首先既然是百分比,那么需要汇总值,先看下

iris.groupby('Species').sum()

结果为:

Sepal.Length  Sepal.Width  Petal.Length  Petal.Width
Species                                                         
setosa             250.3        171.4          73.1         12.3
versicolor         296.8        138.5         213.0         66.3
virginica          329.4        148.7         277.6        101.3

这三个种类的汇总值在这,同时,需要用每一个种类去除三个种类加总的值,而三个种类加总的值为:

iris.iloc[:,0:4].sum()

结果为:

Sepal.Length    876.5
Sepal.Width     458.6
Petal.Length    563.7
Petal.Width     179.9
dtype: float64

可以看到加总值是个Series,而分类汇总是个Dataframe,而Dataframe的列就是Series的index,所以需要用dataframe去除series,直接用/也可以,或者用以下代码:

iris.groupby('Species').sum().div(iris.iloc[:,0:4].sum()) 

看到结果是:

 Sepal.Length  Sepal.Width  Petal.Length  Petal.Width
Species                                                         
setosa          0.285568     0.373746      0.129679     0.068371
versicolor      0.338620     0.302006      0.377861     0.368538
virginica       0.375813     0.324248      0.492461     0.563091

但是到这里还不行,因为行列需要翻转下,因为需要把类别作为行,也就是x轴,然后画图,整体代码就是:

iris.groupby('Species').sum().\
    div(iris.iloc[:,0:4].sum()).T.\
    plot(kind='bar',
         title='prop',
         stacked=True,
         rot=1).\
    legend(loc=1) #旋转坐标轴&#图例位置

后面的stacked就是堆叠,rot=1是旋转xticks,legend(loc=1)是调整图例位置,得到的图形为:
【R和Python对比】matplotlib和ggplot(二)_第7张图片

总结下,柱状图原理很简单,就是data.plot(kind=’bar),其他的复杂逻辑都在数据整形中,python柱状图和excel的画图比较类似,都是使用宽格式,这个和ggplot有典型的区别,因为ggplot只接受长格式的画图,总的对比,py的图形更符合常理,但是操作起来较为繁琐。

下面看下直方图。

基本直方图很简单:

iris['Sepal.Length'].plot(kind='hist',
                          color='k',
                          title='Hist')

【R和Python对比】matplotlib和ggplot(二)_第8张图片

但是正常情况下,都会看几个数据分布的差异,也就用到了复合的直方图:

iris.loc[:,{'Sepal.Width','Petal.Length'}].plot(kind='hist',
                                                alpha=0.5,
                                                title='MultiHist')

【R和Python对比】matplotlib和ggplot(二)_第9张图片

其中alpha和ggplot参数类似,都是调整透明度。

除此之外,还有一种特殊的直方图,是累计直方图,累计直方图和累计密度图类似,把数据从小到大加到100%:

iris.loc[:,{'Sepal.Width','Petal.Length'}].plot(kind='hist',
                                                alpha=0.5,
                                                cumulative=True,
                                                title='Cum-Hist')

【R和Python对比】matplotlib和ggplot(二)_第10张图片

当然,有的时候需要一张图中展示很多直方图(或者其他图),就类似ggplot的facet,分面。具体的代码为:

iris.iloc[:,:4].plot(subplots=True,
                     layout=(2,2),
                     kind='hist',
                     title={'1','2','3','4'})

其中subplots=True的意思是画一个subplot,然后layout就是这个画布的数量,当然kind就是种类。还有一个特征就是TITLE,从图形上看,title是从左下角作为1,然后一个逆时针转到4的:

【R和Python对比】matplotlib和ggplot(二)_第11张图片

最后一个直方图是横向的直方图:

iris['Sepal.Length'].hist(color='k',orientation='horizontal')

【R和Python对比】matplotlib和ggplot(二)_第12张图片

有直方图就有密度图,在ggplot中,只要输入stat=density就是一个密度图了,而python这一点也很简单,但是,需要scipy包的支持

这一点让我蛋疼了好久,因为从pycharm里找不到适合py3.6的scipy包,只能从非官网上下载whl:

http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy

需要下载一个适合python版本的.whl的numpy和scipy:

我的是:

numpy‑1.13.1+mkl‑cp36‑cp36m‑win32.whl
scipy‑0.19.1‑cp36‑cp36m‑win32.whl

下载完成后,需要再命令行(没错,就是ms-dos的命令行)用cd转移环境变量到python下scripts的目录,比如我的就是:

cd C:\\Users\\yangyunru\\AppData\\Local\\Programs\\Python\\Python36-32\\scipts

在这个目录下,把刚才下载的两个whl文件拖到scripts目录下,然后命令行中输入:

pip install  numpy‑1.13.1+mkl‑cp36‑cp36m‑win32.whl
pip install   scipy‑0.19.1‑cp36‑cp36m‑win32.whl

然后才可以使用scipy,也就是才可以画密度图;

密度图原理也很简单,直接输入:

iris['Sepal.Length'].plot(kind='kde',
                          title='Density')

就可以得到:

【R和Python对比】matplotlib和ggplot(二)_第13张图片

同时,一张图中多个density图:

iris.loc[:,{'Sepal.Width','Petal.Length'}].plot(kind='kde',
                                                title='Multidensity')

【R和Python对比】matplotlib和ggplot(二)_第14张图片

当然,也可以分面做密度图

fig=plt.figure() #画布
fig,axe=plt.subplots(1,2,sharey=True)  #共用Y轴
iris['Sepal.Width'].plot(kind='kde',
                         ax=axe[0],
                         title='Sepal.Width') #第一个画Sepal.Width
iris['Sepal.Length'].plot(kind='kde',
                          ax=axe[1],
                          title='Sepal.Length')  #第二个画Sepal.Length

图形为:

【R和Python对比】matplotlib和ggplot(二)_第15张图片

其中sharey=True就是两个共用一个Y轴,更能看出差异;

本章最后一个图形介绍下箱线图:

简单的箱线图就是:

iris.plot(kind='box',
          title='Boxplot')

【R和Python对比】matplotlib和ggplot(二)_第16张图片

如果觉得图形有点丑,改变下参数:

boxcolor=dict(boxes='DarkGreen',
              whiskers='DarkOrange',
              medians='DarkBlue',
              caps='Gray')
iris.plot(kind='box',
          color=boxcolor,
          sym='r+',
          title='Colored-Boxplot') #sym就是异常值的处理,异常值可以认为是长尾

得到:【R和Python对比】matplotlib和ggplot(二)_第17张图片

针对sym这个需要说明下,也就是异常值,上面的小点点或十字;引用百科说法:

在Q3+1.5IQR(四分位距)和Q1-1.5IQR处画两条与中位线一样的线段,这两条线段为异常值截断点,称其为内限;在Q3+3IQR和Q1-3IQR处画两条线段,称其为外限。处于内限以外位置的点表示的数据都是异常值,其中在内限与外限之间的异常值为温和的异常值(mild outliers),在外限以外的为极端的异常值(li)的异常值extreme outliers。
http://wiki.mbalib.com/wiki/%E7%AE%B1%E7%BA%BF%E5%9B%BE

也就是在三分位数+1.5倍的四分位距,其中
四分位距=Q3-Q1

那么超出Q3+1.5(Q3-Q1)都是异常值,同理,Q1-1.5(Q3-Q1)也是异常值。

在看几个箱线图的特例:水平箱线图:

iris.plot(kind='box',
          color=boxcolor,
          vert=False,
          title='H-box') #sym就是异常值的处理

【R和Python对比】matplotlib和ggplot(二)_第18张图片

下面以分组箱线图结束本章:

分组箱线图个人认为是比较常用的图形,可以很明显的看到各个指标的差异,而分组就是按照Species分组了。

首先既然是分组,就需要重塑数据集,然后填充到每一个画布中:

Versicolor=iris.loc[iris['Species']=='versicolor']
Virginica=iris.loc[iris['Species']=='virginica']
Setosa=iris.loc[iris['Species']=='setosa']
fig=plt.figure()
fig,axe=plt.subplots(1,3,sharey=True)
Versicolor.plot(kind='box',ax=axe[0],title='Versicolor')
Virginica.plot(kind='box',ax=axe[1],title='Virginica')
Setosa.plot(kind='box',ax=axe[2],title='Setosa')

前面是设定三个数据集,这三个数据集都是从iris中抽取出来的,分别对应三个种类;然后设定fig画布,并且设定axe,也就是subplot个数,这里是三个;然后分别进行画图,在ax中设定画在aex的哪里,图形如下:
【R和Python对比】matplotlib和ggplot(二)_第19张图片

你可能感兴趣的:(【R和Python对比】matplotlib和ggplot(二))