Chapter3 Decorate Graphs with Plot Styles and Types

本章探索

*线样式自定义
*点样式自定义
*轴刻度自定义
*Matplotlib中可用的多种图类型,比如直方图(histograms)、条形图(bars)、错误条形图(errorbars)、圆形分隔统计图表(pie charts)、散点图(scatter plots)等等。
*极坐标图(Polar charts)
*在我们的图中插入文本信息
标记和线样式(Markers and line styles)
plt.plot(X, Y, '<format>', ...)

Colors、Line styles、Marker styles可以定制。

控制颜色
In [34]: import matplotlib.pyplot as plt

In [35]: import numpy as np

In [36]: y=np.arange(1,3)

In [37]: plt.plot(y,'y')
Out[37]: [<matplotlib.lines.Line2D at 0x20e7962cb00>]

In [38]: plt.plot(y+1,'m')
Out[38]: [<matplotlib.lines.Line2D at 0x20e7b0de470>]

In [39]: plt.plot(y+2,'c')
Out[39]: [<matplotlib.lines.Line2D at 0x20e7b0e45f8>]

In [40]: plt.show()
image.png
image.png
image.png
确定多线图样式

plot()句法可做如下拓展:
plt.plot(x1,y1,fmt1,x2,y2,fmt2,...)

In [45]: import matplotlib.pyplot as plt

In [46]: import numpy as np

In [47]: y=np.arange(1,3)

In [48]: plt.plot(y,'y',y+1,'m',y+2,'c')
image.png
控制线样式
In [49]: import matplotlib.pyplot as plt

In [50]: import numpy as np

In [51]: y = np.arange(1,3)

In [52]: plt.plot(y,'--',y+1,'-.',y+2,':')
Out[52]:
[<matplotlib.lines.Line2D at 0x20e749fb550>,
 <matplotlib.lines.Line2D at 0x20e749fb6a0>,
 <matplotlib.lines.Line2D at 0x20e749fb7f0>]

In [53]:                                    
image.png
image.png
控制标记样式
image.png
image.png
In [53]: import matplotlib.pyplot as plt

In [54]: import numpy as np

In [55]: y=np.arange(1,3,0.2)

In [56]: plt.plot(y,'x',y+0.5,'o',y+1,'D',y+1.5,'^',y+2,'s')
Out[56]:
[<matplotlib.lines.Line2D at 0x20e7964d978>,
 <matplotlib.lines.Line2D at 0x20e7964d320>,
 <matplotlib.lines.Line2D at 0x20e7964d630>,
 <matplotlib.lines.Line2D at 0x20e7962c320>,
 <matplotlib.lines.Line2D at 0x20e7962c908>]

In [57]:                                     
image.png
In [57]: import matplotlib.pyplot as plt

In [58]: import numpy as np

In [59]: y=np.arange(1,3,0.3)

InIn [60]: plt.plot(y,'cx--',y+1,'mo',y+2,'kp-.');
image.png
使用关键字参数的更优控制(Finer control with keyword arguments)

格式化字符串真正有用,但是它们有一些缺陷。例如,不允许我们针对线条和标记确定不同颜色,如我们在前面例子中见到的。

plot()真正是一个丰富的函数,这有许多关键字参数来配置颜色、标记和线条样式。

image.png
------------------------------------------------------------------------------------

Keyword argument Description

------------------------------------------------------------------------------------

Color or c 设置线条颜色;接受任何Matplotlib颜色格式
linestyle 设置线条样式;接受前面见到的线条样式
linewidth 设置线条宽度了接受点的浮点值
marker 设置线条标记样式
markeredgecolor 设置标记边沿颜色;接受任何Matplotlib颜色格式
markerfacecolor 设置标记面部颜色;接受任何Matplotlib颜色格式
markersize 以点的方式设置标记大小;接受浮点值

------------------------------------------------------------------------------------
In [1]: import matplotlib.pyplot as plt

In [2]: import numpy as np

In [3]: y = np.arange(1,3,0.3)
In [4]: plt.plot(y,color='blue',linestyle='dashdot',linewidth=4,marker='o',markerfacecolor='red',markeredgecolor='black
   ...: ',markeredgewidth=3,markersize=12);

In [5]: plt.show()
image.png

前面的屏幕截图不是Matplotlib可以生成的最佳图形,但是它展示了我们手头上许多配置选项。

另一个关键字参数提供的可能性是如果我们画多线图,参数应用于他们所有之中。我们想要画两条绿线,我们可以调用:

plt.plot(x1,y1,x2,y2,color='green')

颜色属性同时应用于这两条线。
这有许多针对标记和线样式的实验,你的想象力是唯一限制。

处理X和Y刻度

我们已经看到在每幅图中的X和Y刻度,但是我们还没有注意到他们明确存在。

垂直和水平刻度是坐标轴上的小段,经常与轴标签耦合使用,用于提供图形上的参考系统。

Matplotlib提供两个基本的函数来管理他们---xticks()和yticks().

参数(表单列表)可以传给函数的是:
*刻度的位置
*画这些位置的标号

用一个例子解释:
In [8]: import matplotlib.pyplot as plt

In [9]: x = [5,3,7,2,4,1]

In [10]: plt.plot(x);

In [11]: plt.xticks(range(len(x)),['a','b','c','d','e','f']);

In [12]: plt.yticks(range(1,8,2));

In [13]: plt.show()
image.png

在这个代码片段,我们使用xticks()来明确位置和标号,yticks()仅显示奇数位置的刻度。

图类型(Plot types)
直方图(Histogram charts)

Matplotlib称直方图为bins。

我们将使用NumPy random.randn()来获取高斯分布中的随机数数组,然后使用hist()函数以直方图格式画出来。

In [14]: import matplotlib.pyplot as plt

In [15]: import numpy as np

In [16]: y = np.random.randn(1000)

In [17]: plt.hist(y);

In [18]: plt.show()
image.png

hist()默认使用bins值10.

hist(y, <bins>)

In [19]: plt.hist(y,25);

In [20]: plt.show()
image.png
错误条形图(Error bar charts)

真实值附近 around the true value

errorbar()函数
例子:
In [21]: import matplotlib.pyplot as plt

In [22]: import numpy as np

In [23]: x = np.arange(0,4,0.2)

In [24]: y=np.exp(-x)

In [25]: e1=0.1 * np.abs(np.random.randn(len(y)))

In [26]: plt.errorbar(x,y,yerr=e1,fmt='.-');

In [27]: plt.show()
image.png
In [21]: import matplotlib.pyplot as plt

In [22]: import numpy as np

In [23]: x = np.arange(0,4,0.2)

In [24]: y=np.exp(-x)

In [25]: plt.errorbar(x,y,xerr=e1,fmt='.-');

In [26]: plt.show()
image.png

注意,对于行,我们使用一个定制的格式,由fmt参数确定。有趣的格式化参数有:

*fmt:这是线条图形格式。如果为None,仅画出没有线条连接他们的错误条形图。
*ecolor:这接受任何的Matplotlib颜色,确定错误星条的颜色。如果为None,使用标记颜色。
*elinewidth:这确定错误条形图的线条宽度。如果为None,使用线条宽度。
*capsize:这确定以像素表示的错误星条图的帽子的大小。

同时使用xerr和yerr:

In [31]: import numpy as np

In [32]: x = np.arange(0,4,0.2)

In [33]: y=np.exp(-x)

In [34]: e1=0.1*np.abs(np.random.randn(len(y)))

In [35]: e2=0.1*np.abs(np.random.randn(len(y)))

In [36]: plt.errorbar(x,y,yerr=e1,xerr=e2,fmt='.-',capsize=0);

In [37]: plt.show()
image.png

上图是对称错误星条图(symmetrical error bars),每个点有4个不同的错误,以及每个对应一个方向:-x,+x,-y和+y。

下面介绍非对称错误星条图(asymmetrical error bars)

In [38]: import matplotlib.pyplot as plt

In [39]: import numpy as np

In [40]: x = np.arange(0,4,0.2)

In [41]: y=np.exp(-x)

In [42]: e1=0.1*np.abs(np.random.randn(len(y)))

In [43]: e2=0.1*np.abs(np.random.randn(len(y)))

In [44]: plt.errorbar(x,y,yerr=[e1,e2],fmt='.-');

In [45]: plt.show()
image.png

在上面代码片段中,-y是e1,+y是e2。

条形图

条形图显示矩形条(垂直或者水平),其长度与表示的值成比例。他们一般用于形象地比较两个或多个值。

Matplotlib中,bar()函数用做生成星条图。该函数期望两列值的列表:X轴坐标,即星条图左边沿的位置以及星条图的高度。

In [46]: import matplotlib.pyplot as plt

In [47]: plt.bar([1,2,3],[3,2,5]);

In [48]: plt.show()
image.png

从上面屏幕截图可见,左边沿起点由第一个列表确定,其高度是第二个列表的值。

Matlibplot设置,条形图宽度默认0.8,(width也是默认关键字参数,用来改变该值),因此我们看见漂亮的分离星条图。如往常,每样东西都是刻度化的,以及自动调整来完美适应图形区域。

可以说星条图是包含在以左底角为起点的一个箱子中的,并由第一个列表明确确定,高度由第二个列表的值确定。星条图的宽度要么是默认值,或者是由width参数确定的。

简要重述箱子的维度:

image.png

从left或者bottom---left,left+height,left+height+width,left+width。

大部分有用的关键字参数列表如下:

  • width: 星条图宽度
  • color: 星条图颜色
  • xerr,yerr:星条图表上的错误星条(是的,bar()支持错误星条)
  • bottom:星条图底部坐标

下面看一个从字典创建一个条形图例子。我们将使用字典值作为条形图的高度,并作为yticks()的参数,而字典键值用做xtick()的位置和条形图的标签。

import matplotlib.pyplot as plt
import numpy as np
dict = {'A':40,'B':70,'C':30,'D':85}
for i, key in enumerate(dict):plt.bar(i,dict[key]);
plt.xticks(np.arange(len(dict))+0.4,dict.keys());
plt.yticks(dict.values());
plt.show()
import matplotlib.pyplot as plt
import numpy as np
data1=10*np.random.rand(5)
data2=10*np.random.rand(5)
data3=10*np.random.rand(5)
e2=0.5*np.abs(np.random.randn(len(data2)))
locs=np.arange(1,len(data1)+1)
width=0.27
plt.bar(locs,data1,width=width);
plt.bar(locs+width,data2,yerr=e2,width=width,color='red');
plt.bar(locs+2*width,data3,width=width,color='green');
plt.xticks(locs+width*1.5,locs);
plt.show()
image.png

在前面的屏幕快照,我们可以看到条形组的颜色有蓝色、红色和绿色(通常顺序),但错误条形的颜色是蓝色(这里是黑色,原因待研究)。

注意width变量的使用:首先,我们使用这个来明确每个条形的宽度是一样的,然后让随后的条形序列以width的倍数开始(这样前面的条形结束,当前的条形开始,将条形打包在一起);最后,我们使用width来放置xticks到“三个条形组”的中间--1.5的倍数,我们获得这个值来座位组的中间。

Matplotlib提供的另外一个类似函数是barh()-画垂直条形图(不是水平的,如bar()那样)。此外,还有其他类型的条形图(up or down,stacked,candlestick bars等等)。

饼图(Pie charts)

饼图是循环表示的,分成扇区(wedges).每个扇区的弧长(arc length)是与我们描述的数量成比例的。这是一种有效表示信息的方式,当我们主要感兴趣的是比较楔子与整个饼,而不是楔子之间比较。

Matplotlib提供函数pie()来根据数组X画饼图。楔子(wedges)是成比例创建的,这样数组X中的每个值x产生一个与x/sum(X)成比例的楔子。

注意,如果sum(X)小于1,那么饼图使用X值直接画,且不做任何限制,最后形成一个不连续的饼。

饼图看上去最佳,如果图形和坐标轴是以平方的格式(如果不是,用普通的矩形图,看起来像椭圆)。

In [101]: import matplotlib.pyplot as plt

In [102]: plt.figure(figsize=(3,3));

In [103]: x=[45,35,20]

In [104]: labels=['Cats','Dogs','Fishes']

In [105]: plt.pie(x,labels=labels);

In [106]: plt.show()
image.png

上图可见饼图颜色递进是蓝色、绿色、红色。
数组X的总和是100,但是我们可以针对楔子明确指定任何值,Matplotlib将会根据这些值来适应这个饼图。

这有一些有趣的关键字参数,我们可以用来定制饼图。

  • explode :如果指定,它是一个与X一样的数组。
  • colors: 这是一个Matplotlib颜色列表,循环地给楔子涂颜色。
  • labels,labeldistance:这是标签列表,X值得每个对应一个。labeldistance是画标签的径向距离。
  • autopct,pctdistance:这种格式字符串或者函数用于标签楔子带数字值。pctdstance是饼图中间和文本开始之间的比例。
  • shadow:这为楔子或者饼图画阴影。
In [108]: import matplotlib.pyplot as plt

In [109]: plt.figure(figsize=(3,3));

In [110]: x=[4,9,21,55,30,18]

In [111]: labels=['Swiss','Austria','Spain','Italy','France','Benelux']

In [112]: explode=[0.2,0.1,0,0,0.1,0]

In [113]: plt.pie(x,labels=labels,explode=explode,autopct='%1.1f%%');

In [114]: plt.show()
image.png

上面饼图的颜色递进关系:蓝色、绿色、红色、蓝绿色、洋红色、黄色。我们可以看到,楔子是从水平坐标轴画的,从右边开始,逆时针移动。

分散图(Scatter plots)

分散图显示两组数据值。数据可视化由点的集合而不是连线完成。每个点的坐标由变量值确定(一个变量确定X轴,另一个变量确定Y轴)。

分散图用于确定两个变量之间的潜在关联,经常在工作于拟合回归函数之前画出。它给出一个好的可视图片的关联性,特别对于非线性关系。

Matplotlib提供scatter()函数来画X versus Y的与分散图同样长度的一维数组(所以这里搜索不到相关性)。

In [115]: import matplotlib.pyplot as plt

In [116]: import numpy as np

In [117]: x=np.random.randn(1000)

In [118]: y=np.random.randn(1000)

In [119]: plt.scatter(x,y)
Out[119]: <matplotlib.collections.PathCollection at 0x17e1c1cf5c0>

In [120]: plt.show()
image.png

采用下面的一些关键字参数来装饰图表:

  • s: 这代表以pixel*pixel标记的大小。可为单个值(用于所有点)或者一组相同的X和Y的大小。(这样每个点都有自己的大小)
    *c: 这是点的颜色。它可以是单个值或者颜色列表(绘制的点中循环)最终是X和Y相同的大小。这些值可以是Matplotlib颜色编码或者甚至是采用颜色映射映射到颜色的数字。
    *marker: 这确定标记用于画点;可用值如下:


    image.png
In [122]: size=50*np.random.randn(1000)

In [123]: colors=np.random.rand(1000)

In [124]: plt.scatter(x,y,s=size,c=colors);
c:\python36\lib\site-packages\matplotlib\collections.py:857: RuntimeWarning: invalid value encountered in sqrt
  scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor

In [125]: plt.show()
c:\python36\lib\site-packages\matplotlib\collections.py:857: RuntimeWarning: invalid value encountered in sqrt
  scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor
image.png
极坐标图(Polar charts)

polar() Matplotlib函数画极坐标图。其参数是两个列表(长度相同)---theta对应角度坐标,r对应径向坐标。

In [126]: import matplotlib.pyplot as plt

In [127]: import numpy as np

In [128]: theta=np.arange(0.,2.,1./180.)*np.pi

In [129]: plt.polar(3*theta,theta/5);

In [130]: plt.polar(theta,np.cos(4*theta));

In [131]: plt.polar(theta,[1.4]*len(theta));

In [132]: plt.show()
image.png
极坐标图的导航工具栏

pan()和zoom()函数

控制半径和角度网格

rgrid()
thetadrid()
rgrids()
我们可以传递的参数:
radii:网格线可画的径向距离。
labels:在radii网格显示的标签。
angle:标签显示的角度(默认22.5度)。

In [133]: import matplotlib.pyplot as plt

In [134]: import numpy as np

In [135]: theta=np.arange(0.,2.,1./180.)*np.pi

In [136]: r=np.abs(np.sin(5*theta)-2.*np.cos(theta))

In [137]: plt.polar(theta,r);

In [138]: plt.thetagrids(range(45,360,90));

In [139]: plt.rgrids(np.arange(0.2,3.1,.7),angle=0);

In [140]: plt.show()
image.png
图片、注释和箭头中的文本
图片中的文本

xlabel()
ylabel()
title()
text()函数---在任意一个位置写一个字符串(text):
plt.text(x,y,text)

画sine函数图,添加注释说明sin(0)等于0.

In [141]: import matplotlib.pyplot as plt

In [142]: import numpy as np

In [143]: x=np.arange(0,2*np.pi,.01)

In [144]: y=np.sin(x)

In [145]: plt.plot(x,y)
Out[145]: [<matplotlib.lines.Line2D at 0x17e15a31860>]

In [146]: plt.text(0.1,-0.04,'sin(0)=0');

In [147]: plt.show()
image.png
注释

annotate()函数提供功能来让注释容易。在一个注释中,我们不得不考虑两点-我们想要注释的图片要点(由一个xy关键字参数表示的)和我们要放置注释文本位置的图片位置(由xytext表示)。他们都以数据坐标位置(x,y)格式表示。

此外,这有一个额外的参数来明确箭头特性,那就是text()和annotate()的功能差异。我们用箭头连接注释文本到注释要点。

In [1]: import matplotlib.pyplot as plt

In [2]: y=[13,11,13,12,13,10,30,12,11,13,12,12,12,11,12]

In [3]: plt.plot(y);

In [4]: plt.ylim(ymax=35);

In [5]: plt.annotate('this spot must really\nmeansomething',xy=(6,30),xytext=(8,31.5),arrowprops=dict(facecolor='black'
   ...: ,shrink=0.05));

In [6]: plt.show()
image.png

注意关于缩放(shrink)特性。
一些有趣的参数是:
*width: 点的箭头宽度。
*frac: 箭头碎片头部占用的长度。
*headwidth:点的箭头基本宽度。
*shrink:(0.05=5%)

箭头(Arrows)

箭头起点(x,y),箭头终点(x+dx,y+dy)。
plt.arrow(x,y,dx,dy)
很不幸,这个函数相当难用。

plt.anotate("",...)

总结:
• How we can customize the markers and lines representation
• How we can adjust the visualization of ticks on plot axes
• How we can use different plot types—histograms, error bars, bars, pies,scatters charts, and so on
• How we can generate polar charts, and the peculiarities they have
• How we can describe the plots, either by adding text or annotating (using text and arrows) the plot, and how we can draw arrows alone Matplotlib still has a lot to show us, in particular, for advanced users and purposes. The next chapter will introduce the object-oriented world of Matplotlib, and much more.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容