Python -Matplotlib库绘制图形(附代码实例)

Python -Matplotlib库绘制图形

参考文献链接:
https://blog.csdn.net/qq_34859482/article/details/80617391
https://www.cnblogs.com/xmcwm/p/11831492.html

一,Axes介绍(基础)

matplotlib: 最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建

官网 https://matplotlib.org/

在绘图结构中,figure创建窗口,subplot创建子图。所有的绘画只能在子图上进行。plt表示当前子图,若没有就创建一个子图。所有你会看到一些教程中使用plt进行设置,一些教程使用子图属性进行设置。他们往往存在对应功能函数。

Figure:面板(图),matplotlib中的所有图像都是位于figure对象中,一个图像只能有一个figure对象。

Subplot:子图,figure对象下创建一个或多个subplot对象(即axes)用于绘制图像。

1.1 Figure

在任何绘图之前,我们需要一个Figure对象,可以理解成我们需要一张画板才能开始绘图。

import matplotlib.pyplot as plt
fig = plt.figure()

1.2 Axes

在拥有Figure对象之后,在作画前我们还需要轴,没有轴的话就没有绘图基准,所以需要添加Axes。也可以理解成为真正可以作画的纸。

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set(xlim=[0.5, 4.5], ylim=[-2, 8], title='An Example Axes',
       ylabel='Y-Axis', xlabel='X-Axis')
plt.show()

对于上面的fig.add_subplot(111)就是添加Axes的,参数的解释的在画板的第1行第1列的第一个位置生成一个Axes对象来准备作画。也可以通过fig.add_subplot(2, 2, 1)的方式生成Axes,前面两个参数确定了面板的划分,例如 2, 2会将整个面板划分成 2 * 2 的方格,第三个参数取值范围是 [1, 2*2] 表示第几个Axes。如下面的例子:

fig = plt.figure()  #创建一个figure对象,相当于一个画板
ax1 = fig.add_subplot(221) #添加子图对象, "221" :2*2方格,第1块(共四块)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(224)

1.3 Multiple Axes

可以发现我们上面添加 Axes 似乎有点弱鸡,所以提供了下面的方式一次性生成所有 Axes:

fig, axes = plt.subplots(nrows=2, ncols=2) #直接生成2*2四个子图,不需要使用fig.add_subplot方法
axes[0,0].set(title='Upper Left')  #以二维数组的形式访问
axes[0,1].set(title='Upper Right')
axes[1,0].set(title='Lower Left')
axes[1,1].set(title='Lower Right')

<img src="C:\Users\ZBW\AppData\Roaming\Typora\typora-user-images\1583514306530.png" alt="1583514306530" style="zoom: 33%;" / width="20%">

1.4 Axes Vs .pyplot

相信不少人看过下面的代码,很简单并易懂,但是下面的作画方式只适合简单的绘图,快速的将图绘出。在处理复杂的绘图工作时,我们还是需要使用 Axes 来完成作画的。

plt.plot([1, 2, 3, 4], [30, 20, 15, 25], color='lightblue', linewidth=3)
plt.show()`在这里插入代码片`

二,图形绘制

在这里插入图片描述
绘制图形所使用的库:

import matplotlib.pyplot as plt
import numpy as np

2.1散点图

只画点,但是不用线连接起来。

x = np.arange(10)
y = np.random.randn(10)
plt.scatter(x, y, color='green', marker='*') #点已经添加,下面为可选项

plt.xlabel("x_labels") #添加x轴标签
plt.ylabel("x_labels") #添加y轴标签
plt.title("This is a scatter table")  #添加表格标题
plt.grid()  #添加网格线

plt.show()

2.2 条形图

条形图分两种,一种是水平的,一种是垂直的,见下例子:

np.random.seed(1)
x = np.arange(5)
y = np.random.randn(5)

fig, axes = plt.subplots(ncols=2,nrows=1) #1行2列

vert_bars = axes[0].bar(x, y, color='lightblue', align='center')    #水平条形图
horiz_bars = axes[1].barh(x, y, color='lightblue', align='center')  #垂直条形图

#在水平或者垂直方向上画线
axes[0].axhline(0, color='gray', linewidth=2)
axes[1].axvline(0, color='gray', linewidth=2)
plt.show()

​ 条形图还返回了一个Artists 数组,对应着每个条形,例如上图 Artists 数组的大小为5,我们可以通过这些 Artists 对条形图的样式进行更改,如下例:

np.random.seed(1)
x = np.arange(5)
y = np.random.randn(5)

fig, ax = plt.subplots()
vert_bars = ax.bar(x, y, color='lightblue', align='center')

for bar, height in zip(vert_bars, y):
    #在坐标轴下方的图形进行特殊处理
    if height < 0:
        bar.set(edgecolor='darkred', color='greenyellow', linewidth=10)

plt.show()

2.3 直方图

直方图用于统计数据出现的次数或者频率,有多种参数可以调整,见下例:

np.random.seed(19680801)

n_bins = 10
x = np.random.randn(1000, 3)

fig, axes = plt.subplots(nrows=2, ncols=2)
ax0, ax1, ax2, ax3 = axes.flatten()

colors = ['red', 'tan', 'lime']
ax0.hist(x, n_bins, density=True, histtype='bar', color=colors, label=colors)
ax0.legend(prop={'size': 10})      #legend方法 设置图例
ax0.set_title('bars with legend')  #添加标题

ax1.hist(x, n_bins, density=True, histtype='barstacked')
ax1.set_title('stacked bar')

ax2.hist(x, histtype='barstacked', rwidth=0.9)

ax3.hist(x[:, 0], rwidth=0.9)
ax3.set_title('different sample sizes')

fig.tight_layout() #自动调整子绘图参数
plt.show()


参数中**density**控制Y轴是概率还是数量,与返回的第一个的变量对应。histtype控制着直方图的样式,默认是 ‘bar’,对于多个条形时就相邻的方式呈现如子图1, ‘barstacked’ 就是叠在一起,如子图2、3。 rwidth 控制着宽度,这样可以空出一些间隙,比较图2、3. 图4是只有一条数据时。

2.4 饼图

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0, 0)  # only "explode" the 2nd slice (i.e. 'Hogs')

fig1, (ax1, ax2) = plt.subplots(2)
ax1.pie(sizes, labels=labels, autopct='%1.1f%%', shadow=True)
ax1.axis('equal')
ax2.pie(sizes, autopct='%1.2f%%', shadow=True, startangle=90, explode=explode,pctdistance=1.12)
ax2.axis('equal')
ax2.legend(labels=labels, loc='upper right')

plt.show()

饼图自动根据数据的百分比画饼.。labels是各个块的标签,如子图一。autopct=%1.1f%%表示格式化百分比精确输出,explode,突出某些块,不同的值突出的效果不一样。pctdistance=1.12百分比距离圆心的距离,默认是0.6.

2.5 箱形图

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(15,7), dpi=80) #figsize=(x,y)-->设置画布大小, dpi-->像素

#matplotlib默认不支持中文和符号和字符,加入下面两行代码,使其能够显示中文和符号
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

x = (np.array([1908.3, 3158.2, 4140.6, 5510.2, 2015.3, 3235.0, 4453.8, 5798.4,
               2147.6, 3385.8, 4731.2, 5925.6, 2222.5, 3447.2, 5046.1, 6254.4]),
     np.array([9548.0, 11127.5, 11887.0, 13102.3, 10641.7, 12312.9, 12790.3,
               13915.8, 11320.0, 13300.1, 14024.3, 15461.0, 13146.6, 15219.9]),
     np.array([9873.6, 9757.7, 9684.9, 10581.7, 11429.4, 11178.6, 11089.3, 12002.6,
               12827.3, 12508.9, 12501.8, 13583.8, 14456.4, 13870.2, 13946.9])
     )
labels = ["第一产业", "第二产业", "第三产业"]
plt.boxplot(x, notch=True, labels=labels, meanline=True, showmeans=True)

plt.title("生产总值箱线图")
plt.xlabel("产业", verticalalignment="top",color ='red')
plt.ylabel("生产总值(亿元)", rotation=0, horizontalalignment="right")
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d3GhPYVD-1583519864143)(C:\Users\ZBW\AppData\Roaming\Typora\typora-user-images\1583518444106.png)]

三 布局、图例说明、边界

3.1区间上下限

当绘画完成后,会发现X、Y轴的区间是会自动调整的,并不是跟我们传入的X、Y轴数据中的最值相同。为了调整区间我们使用下面的方式:

ax.set_xlim([xmin, xmax])   #设置X轴的区间
ax.set_ylim([ymin, ymax])   #Y轴区间
ax.axis([xmin, xmax, ymin, ymax])   #X、Y轴区间
ax.set_ylim(bottom=-10)     #Y轴下限
ax.set_xlim(right=25)       #X轴上限

具体效果见下例:

x = np.linspace(0, 2*np.pi)
y = np.sin(x)
fig, (ax1, ax2) = plt.subplots(2)
ax1.plot(x, y)
ax2.plot(x, y)
ax2.set_xlim([-1, 6])
ax2.set_ylim([-1, 3])
plt.show()

3.2 图例说明

我们如果我们在一个Axes上做多次绘画,那么可能出现分不清哪条线或点所代表的意思。这个时间添加图例说明,就可以解决这个问题了,见下例:

fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [10, 20, 25, 30], label='Philadelphia')
ax.plot([1, 2, 3, 4], [30, 23, 13, 4], label='Boston')
ax.scatter([1, 2, 3, 4], [20, 10, 30, 15], label='Point')
ax.set(ylabel='Temperature (deg C)', xlabel='Time', title='A tale of two cities')
ax.legend()
plt.show()

在绘图时传入 label 参数,并最后调用ax.legend()显示图例说明 对于 legend 合适传入参数,控制图例说明显示的位置:

Location String Location Code
‘best’ 0
‘upper right’ 1
‘upper left’ 2
‘lower left’ 3
‘lower right’ 4
‘right’ 5
‘center left’ 6
‘center right’ 7
‘lower center’ 8
‘upper center’ 9
‘center’ 10

3.3 区间分段

默认情况下,绘图结束之后,Axes 会自动的控制区间的分段。见下例:

data = [('apples', 2), ('oranges', 3), ('peaches', 1)]
fruit, value = zip(*data)

fig, (ax1, ax2) = plt.subplots(2)
x = np.arange(len(fruit))
ax1.bar(x, value, align='center', color='gray')
ax2.bar(x, value, align='center', color='gray')

ax2.set(xticks=x, xticklabels=fruit)

#ax.tick_params(axis='y', direction='inout', length=10) #修改 ticks 的方向以及长度
plt.show()

3.4 布局

当我们绘画多个子图时,就会有一些美观的问题存在,例如子图之间的间隔,子图与画板的外边间距以及子图的内边距,下面说明这个问题:

fig, axes = plt.subplots(2, 2, figsize=(9, 9))
fig.subplots_adjust(wspace=0.5, hspace=0.3,
                    left=0.125, right=0.9,
                    top=0.9,    bottom=0.1)

#fig.tight_layout() #自动调整布局,使标题之间不重叠
plt.show()

通过fig.subplots_adjust()我们修改了子图水平之间的间隔wspace=0.5,垂直方向上的间距hspace=0.3,左边距left=0.125 等等,这里数值都是百分比的。以 [0, 1] 为区间,选择left、right、bottom、top 注意 top 和 right 是 0.9 表示上、右边距为百分之10。不确定如果调整的时候,fig.tight_layout()是一个很好的选择。之前说到了内边距,内边距是子图的,也就是 Axes 对象,所以这样使用 ax.margins(x=0.1, y=0.1),当值传入一个值时,表示同时修改水平和垂直方向的内边距。

3.5 轴相关

改变边界的位置,去掉四周的边框:

fig, ax = plt.subplots()
ax.plot([-2, 2, 3, 4], [-10, 20, 25, 5])
ax.spines['top'].set_visible(False)     #顶边界不可见
ax.xaxis.set_ticks_position('bottom')  # ticks 的位置为下方,分上下的。
ax.spines['right'].set_visible(False)   #右边界不可见
ax.yaxis.set_ticks_position('left')  

# "outward"
# 移动左、下边界离 Axes 10 个距离
#ax.spines['bottom'].set_position(('outward', 10))
#ax.spines['left'].set_position(('outward', 10))

# "data"
# 移动左、下边界到 (0, 0) 处相交
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))

# "axes"
# 移动边界,按 Axes 的百分比位置
#ax.spines['bottom'].set_position(('axes', 0.75))
#ax.spines['left'].set_position(('axes', 0.3))

plt.show()

四、相关方法

4.1、配置参数:

axex 设置坐标轴边界和表面的颜色、坐标刻度值大小和网格的显示
figure 控制dpi、边界颜色、图形大小、和子区( subplot)设置
font 字体集(font family)、字体大小和样式设置
grid 设置网格颜色和线性
legend 设置图例和其中的文本的显示
line 设置线条(颜色、线型、宽度等)和标记
patch 是填充2D空间的图形对象,如多边形和圆。控制线宽、颜色和抗锯齿设置等。
savefig 可以对保存的图形进行单独设置。例如,设置渲染的文件的背景为白色。
verbose 设置matplotlib在执行期间信息输出,如silent、helpful、debug和debug-annoying。
xticks 和yticks 为x,y轴的主刻度和次刻度设置颜色、大小、方向,以及标签大小。

4.2、线条相关属性标记设置

线条风格linestyle或ls 描述
‘-‘ 实线
‘:’ 虚线
‘–’ 破折线
‘None’,’ ‘,’’ 什么都不画
‘-.’ 点划线

4.3、线条标记

标记maker            描述

‘o’                 圆圈  
‘.’                 点
‘D’                 菱形  
‘s’                 正方形
‘h’                 六边形1*’                 星号
‘H’                 六边形2    
‘d’                 小菱形
‘_’                 水平线 
‘v’                 一角朝下的三角形
‘8’                 八边形 
‘<’                 一角朝左的三角形
‘p’                 五边形 
‘>’                 一角朝右的三角形
‘,’                 像素  
‘^’                 一角朝上的三角形
‘+’                 加号  
‘\  ‘               竖线
‘None,’’,’ ‘       无   
‘x’                 X

4.4、颜色

别名             颜色   

b               蓝色  
g               绿色
r               红色  
y               黄色
c               青色
k               黑色   
m               洋红色 
w               白色

如果这些颜色不够用,还可以通过两种其他方式来定义颜色值:

1、使用HTML十六进制字符串 color=’#123456’ 使用合法的HTML颜色名字(’red’,’chartreuse’等)。

+’                 加号  
‘\  ‘               竖线
‘None,’’,’ ‘       无   
‘x’                 X
发布了21 篇原创文章 · 获赞 29 · 访问量 2815

猜你喜欢

转载自blog.csdn.net/VariatioZbw/article/details/104708572