python模块matplotlib.pyplot用法_03_Python 使用Matplotlib绘图

本文介绍了如何使用Python的Matplotlib模块进行数据分析绘图,包括基础用法、线条样式修改、直方图、柱状图和散点图绘制。此外,还展示了如何结合Numpy实现一个简单的扫雷游戏,通过实例演示了模块的强大功能。
摘要由CSDN通过智能技术生成

2019.5.13

不知不觉,已经进入第12周了,Python数据分析的学习现今也已经进入了中后期,在继上周进行了Numpy的康威生命游戏的编写之后;紧接着进行的学习就是利用Python的Matplotlib模块来练习绘图。这次由于涉及到图像,所以引用了一些丁烨老师的pdf的截图。主要是进行用Matplotlib模块来进行MATLAB能做的数据分析绘图工作,并结合Numpy和Matplotlib来做一个扫雷小游戏。

5fb98e18d6d3

matplotlib

一. Matplotlib模块

1. 概述

Matplotlib是一个Python 2D绘图库,可以生成各种硬拷贝格式和跨平台的交互式环境的出版物质量数据。只需几行代码即可生成绘图,直方图,功率谱,条形图,错误图,散点图等。 对于简单的绘图,pyplot模块提供了类似MATLAB的接口,特别是与IPython结合使用时。而我们进行数据分析就是在使用这个模块。 对于高级用户,您可以通过面向对象的界面或MATLAB用户熟悉的一组函数完全控制线型,字体属性,轴属性等。

2. 基本用法

基本概念

(图片源自丁烨老师的讲义pdf,侵权删)

5fb98e18d6d3

绘图的基本概念01.png

5fb98e18d6d3

绘图的基本概念02.png

5fb98e18d6d3

绘图的基本概念03.png

5fb98e18d6d3

绘图的基本概念04.png

数据准备

输入数据应当是 np.array 或 np.ma.masked_array 格式 。

其他类似数组的格式,例如标准库的 list、Pandas 的 pandas.DataFrame、NumPy 的 np.matrix 等也可能能用。

在绘制图表前,最好将输入格式转换为 np.array。

函数讲解

matplotlib.pyplot.plot()

plot()用于在figure上画出曲线图,其中比较值得注意的参数有 x, y, label, 样式等。x, y决定了曲线的形状,即哪些点(可传入特定点,或者x ** 2等函数方式)。label决定了曲线的名字。样式决定了图像中的点的颜色,样式,线的样子。

from matplotlib import pyplot as plt

import numpy as np

x = np.linspace(0, 2, 100) # 利用numpy创建一个矩阵,方便用于数据输入

plt.plot(x, x, label='linear') # 画出直线 y=x

plt.plot(x, x**2, label='quadratic') # 画出曲线 y = x²

plt.plot(x, x**3, label='cubic') # 画出曲线 y = x^3

plt.xlabel('x label') # 设置x轴名称

plt.ylabel('y label') # 设置y轴名称

plt.title("Simple Plot") # 设置图片的标题

plt.legend() # 画出一个图例,用于标出什么颜色和样式的线代表什么

plt.show()

5fb98e18d6d3

sample plot.png

线条的样式

5fb98e18d6d3

修改图片的样式01.png

5fb98e18d6d3

修改图片的样式02.png

from matplotlib import pyplot as plt

plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro') # 根据表格可知,画出的图形是红色的圈

plt.axis([0, 6, 0, 20])

plt.show()

5fb98e18d6d3

样式使用案例.png

其他几种绘图的函数

matplotlib.pyplot.hist() 用于绘制直方图

matplotlib.pyplot.bar() 用于绘制柱状图

matplotlib.pyplot.scatter() 用于绘制散点图

from matplotlib import pyplot as plt

import numpy as np

mu, sigma = 100, 15

x = mu + sigma * np.random.randn(10000)

# the histogram of the data

n, bins, patches = plt.hist( x, 50, density=1, facecolor='g', alpha=0.75 )

plt.xlabel('Smarts')

plt.ylabel('Probability')

plt.title('Histogram of IQ')

plt.text(60, .025, r'$\mu=100,\ \sigma=15$')

plt.axis([40, 160, 0, 0.03])

plt.grid(True)

plt.show()

5fb98e18d6d3

绘制直方图.png

from matplotlib import pyplot as plt

names = ['group_a', 'group_b', 'group_c'] # 用一个列表存储三个图的名字

values = [1, 10, 100] # 用列表存储用到的点

plt.figure(1, figsize=(9, 3)) # 创建一副图

plt.subplot(131) # 创建子图

plt.bar(names, values) # 绘制柱状图

plt.subplot(132)

plt.scatter(names, values) # 绘制散点图

plt.subplot(133)

plt.plot(names, values) # 绘制曲线图

plt.suptitle('Categorical Plotting')

plt.show()

5fb98e18d6d3

其他类型的绘图.png

绘制子图

import numpy as np

from matplotlib import pyplot as plt

def f(t):

return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)

t2 = np.arange(0.0, 5.0, 0.02)

plt.figure(1)

plt.subplot(211)

plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.subplot(212)

plt.plot(t2, np.cos(2*np.pi*t2), 'r--')

plt.show()

5fb98e18d6d3

绘制子图.png

二.利用Numpy和matplotlib.pyplot来实现扫雷游戏

效果图

5fb98e18d6d3

扫雷01.png

5fb98e18d6d3

扫描02.png

源代码

import matplotlib.pyplot as plt

import numpy as np

from matplotlib.patches import RegularPolygon

from scipy.signal import convolve2d

class MineSweeper(object):

"""docstring for MineSweeper"""

covered_color = '#DDDDDD'

uncovered_color = '#AAAAAA'

edge_color = '#888888'

count_colors = ['none', 'blue', 'green', 'red', 'darkred', 'darkgreen', 'black', 'black']

flag_vertices = np.array([[0.25, 0.2], [0.25, 0.8], [0.75, 0.65], [0.25, 0.5]])

@classmethod

def beginner(cls):

return cls(8, 8, 10)

@classmethod

def intermediate(cls):

return cls(16, 16, 40)

@classmethod

def expert(cls):

return cls(30, 16, 99)

def __init__(self, width, height, nmines):

self.width, self.height, self.nmines = width, height, nmines

# Create the figure and axes

self.fig = plt.figure(figsize=((width + 2) / 3., (height + 2) / 3.))

self.ax = self.fig.add_axes(

(0.05, 0.05, 0.9, 0.9),

aspect='equal',

frameon=False,

xlim=(-0.05, width + 0.05),

ylim=(-0.05, height + 0.05))

for axis in (self.ax.xaxis, self.ax.yaxis):

axis.set_major_formatter(plt.NullFormatter())

axis.set_major_locator(plt.NullLocator())

# Create the grid of squares

self.squares = np.array([[RegularPolygon(

(i + 0.5, j + 0.5),

numVertices=4,

radius=0.5 * np.sqrt(2),

orientation=np.pi / 4,

ec=self.edge_color,

fc=self.covered_color

) for j in range(height)] for i in range(width)])

[self.ax.add_patch(sq) for sq in self.squares.flat]

# Define internal state variables

self.mines = None

self.counts = None

self.clicked = np.zeros((self.width, self.height), dtype=bool)

self.flags = np.zeros((self.width, self.height), dtype=object)

self.game_over = False

# Create event hook for mouse clicks

self.fig.canvas.mpl_connect('button_press_event', self._button_press)

def _draw_mine(self, i, j):

self.ax.add_patch(plt.Circle((i + 0.5, j + 0.5), radius=0.25, ec='black', fc='black'))

def draw_red_x(self, i, j):

self.ax.text(i + 0.5, j + 0.5, 'X', color='r', fontsize=20, ha='center', va='center')

def _toggle_mine_flag(self, i, j):

if self.clicked[i, j]:

pass

elif self.flags[i, j]:

self.ax.patches.remove(self.flags[i, j])

self.flags[i, j] = None

else:

self.flags[i, j] = plt.Polygon(self.flag_vertices + [i, j], fc='red', ec='black', lw=2)

self.ax.add_patch(self.flags[i, j])

def _reveal_unmarked_mines(self):

for (i, j) in zip(*np.where(self.mines & ~self.flags.astype(bool))):

self._draw_mine(i, j)

def _cross_out_wrong_flags(self):

for (i, j) in zip(*np.where(self.mines & ~self.flags.astype(bool))):

self.draw_red_x(i, j)

def _mark_remaining_mines(self):

for (i, j) in zip(*np.where(self.mines & ~self.flags.astype(bool))):

self._toggle_mine_flag(i, j)

def _setup_mines(self, i, j):

# Randomly place mines on a grid, but not on space (i, j)

idx = np.concatenate([

np.arange(i * self.height + j),

np.arange(i * self.height + j + 1, self.width * self.height)

])

np.random.shuffle(idx)

self.mines = np.zeros((self.width, self.height), dtype=bool)

self.mines.flat[idx[:self.nmines]] = 1

# Count the number of mines bordering each square

self.counts = convolve2d(self.mines.astype(complex), np.ones((3, 3)), mode='same').real.astype(int)

def isclicked(self, i, j):

# to deal with the situation that the square is clikced

# If the clicked square's number equals to the numbers of flags surrounded,

# open all of squares surrounded it expect the flaged one

count = 0

for ii in range(max(0, j - 1), min(self.width, i + 2)):

for jj in range(max(0, j - 1), min(self.height, j + 2)):

if self.flags[ii, jj]:

count = count + 1

if count == self.counts[i, j]:

for ii in range(max(0, j - 1), min(self.width, i + 2)):

for jj in range(max(0, j - 1), min(self.height, j + 2)):

if (self.flags[ii, jj] == 0) and (self.clicked[ii, jj] == False):

# why it goes wrong when I write like xxx is False?

self.clicked[ii, jj] = True

if self.mines[ii, jj]:

self.squares[ii, jj].set_facecolor(self.uncovered_color)

self._draw_mine(ii, jj)

self.draw_red_x(ii, jj)

elif self.counts[ii, jj] == 0:

self.squares[ii, jj].set_facecolor(self.uncovered_color)

else:

self.squares[ii, jj].set_facecolor(self.uncovered_color)

self.ax.text(

ii + 0.5, jj + 0.5,

str(self.counts[ii, jj]),

color=self.count_colors[self.counts[ii, jj]],

ha='center', va='center', fontsize=18,

fontweight='bold'

)

return

def _click_square(self, i, j):

# If this is the first click, then set up the mines

if self.mines is None:

self._setup_mines(i, j)

# If there is a flag or square is already clicked, do nothing

if self.flags[i, j]:

return

if self.clicked[i, j]:

self.isclicked(i, j)

return

# Mark this mines is clicked

self.clicked[i, j] = True

# Hit a mine: game over

if self.mines[i, j]:

self.game_over = True

self._reveal_unmarked_mines()

self.draw_red_x(i, j)

self._cross_out_wrong_flags()

# Square with no surrounding mines: Clear out all adjacent squares

elif self.counts[i, j] == 0:

self.squares[i, j].set_facecolor(self.uncovered_color)

for ii in range(max(0, j - 1), min(self.width, i + 2)):

for jj in range(max(0, j - 1), min(self.height, j + 2)):

self._click_square(ii, jj)

# Hit an empty square: reveal the number

else:

self.squares[i, j].set_facecolor(self.uncovered_color)

self.ax.text(

i + 0.5, j + 0.5,

str(self.counts[i, j]),

color=self.count_colors[self.counts[i, j]],

ha='center', va='center', fontsize=18,

fontweight='bold'

)

# If all remaining squares are mines, mark them and end game

if self.mines.sum() == (~self.clicked).sum():

self.game_over = True

self._mark_remaining_mines()

def _button_press(self, event):

if self.game_over or (event.xdata is None) or (event.ydata is None):

return

i, j = map(int, (event.xdata, event.ydata))

if i < 0 or j < 0 or i >= self.width or j >= self.height:

return

# Left mouse button: reveal square

if event.button == 1:

self._click_square(i, j)

# Right mouse button: mark or unmark flag

elif (event.button == 3) and (not self.clicked[i, j]):

self._toggle_mine_flag(i, j)

self.fig.canvas.draw()

if __name__ == '__main__':

ms = MineSweeper.beginner()

plt.show()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值