使用matplotlib绘制3D图表和统计地图

目录

使用mplot3D绘制3D图表

mplot3d概述

绘制3D线框图(plot_wireframe())

绘制3D曲面图(plot_surface())

绘制3D条形图

 绘制3D柱形图

np.meshgrid()函数的补充

使用animation制作动图

例子1

 例子2

使用basemap绘制统计地图

实例:美国部分城镇人口分布(basemap)

实例1:三维空间的星星(3D散点图)

实例2:三维空间闪烁的星星(3D动图)

编程题(动点)

总结


使用mplot3D绘制3D图表

mplot3d概述

'''Axes3D()方法
Axes3D(fig, rect=None, *args, azim=-60, zscale=None,
       sharez=None, prooj_type='persp', **kwargs)
该方法的参数fig表示所属画布,rect表示确定三维坐标系位置的元组
'''
# 创建Axes3D类对象的示例代码如下:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)

使用matplotlib绘制3D图表和统计地图_第1张图片


'''
官方推荐
add_suplot()方法
在调用add_suplot()方法添加绘图区域时为该方法传入projection='3d',
即指定坐标系的类型为三维坐标系,返回一个Axes3D类的对象
'''
# 创建Axes3D类对象的示例代码如下:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

使用matplotlib绘制3D图表和统计地图_第2张图片


绘制3D线框图(plot_wireframe())

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 获取测试数据
X, Y, Z = axes3d.get_test_data(0.05)
# 绘制 3D线框图
ax.plot_wireframe(X, Y, Z, # 表示x、y、z轴的数据
                  rstride=10, cstride=10 # 表示采样的密度。
                  # 若使用参数rstride或cstride中任意一个,则另一个参数默认为0
                  # rcount,ccount:表示每个坐标轴方向所使用的最大样本量,默认为50
                  # 注意:参数rstride、cstride与参数rcount、ccount是互斥关系,它们不能同时使用
                 )
plt.show()

使用matplotlib绘制3D图表和统计地图_第3张图片


绘制3D曲面图(plot_surface())

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
# 数据
x1 = np.arange(-5, 5, 0.25)
y1 = np.arange(-5, 5, 0.25)
# 对数据进行小处理
x1, y1 = np.meshgrid(x1, y1) # X, Y = np.meshgrid(x, y) 代表的是将x中每一个数据和y中每一个数据组合生成很多点,然后将这些点的x坐标放入到X中,y坐标放入Y中,并且相应位置是对应的
r1 = np.sqrt(x1** 2 + y1 ** 2)
z1 = np.sin(r1)
# 画布
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 绘制曲面图
ax.plot_surface(x1, y1, z1, # 数据
                cmap=cm.coolwarm, # 曲面颜色映射表
                linewidth=0,
               ) 
# 设置 z 轴刻度的范围
ax.set_zlim(-1.01, 1.01)
plt.show()

使用matplotlib绘制3D图表和统计地图_第4张图片

 


绘制3D条形图

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
import numpy as np

plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.sans-serif'] = ['SimHei']

# 创建画布
fig = plt.figure()

# 创建3D坐标系
axes3d = Axes3D(fig)
# 数据
zs = range(5)
left = np.arange(0, 10)
height = np.array([])
for i in range(len(zs)):
    z = zs[i] # 0,1,2,3,4
    height = np.random.randint(0, 30, size=10)
    axes3d.bar(left, # y轴数据
               height, # z轴数据
               zs=z, # x轴数据
               zdir='x',
               color=['red', 'green', 'purple', 'yellow', 'blue', 'black', 'gray', 'orange', 'pink', 'cyan'])
plt.xticks(zs, ['1月份', '2月份', '3月份', '4月份', '5月份'])  # x轴标签
plt.yticks(left, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'G']) # y轴标签
plt.xlabel('月份') 
plt.ylabel('型号')
plt.show()

使用matplotlib绘制3D图表和统计地图_第5张图片


 绘制3D柱形图

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.rcParams['font.sans-serif'] = ['SimHei']

# 数据
color = ["blue", "cornflowerblue", "mediumturquoise", "goldenrod", "yellow"]
lambda1 = lambda2 = [10 ** x for x in range(-2, 3)]
# [0.01, 0.1, 1, 10, 100]

# x, y: position
x = list(range(len(lambda1)))
y = list(range(len(lambda2)))
# [0, 1, 2, 3, 4]


x_tickets = [str(_x) for _x in lambda1] # 将其转换为string类型
y_tickets = [str(_x) for _x in lambda2]
# ['0.01', '0.1', '1', '10', '100']

# acc = np.random.rand(len(x), len(y))
acc = np.arange(len(x) * len(y)).reshape(len(x), len(y)) + 1 # 转换为5行5列的二维数组,第一位为1
acc = acc / acc.max()

xx, yy = np.meshgrid(x, y)# 将x中每一个数据和y中每一个数据组合生成很多点,然后将这些点的x坐标放入到xx中,y坐标放入yy中,并且相应位置是对应的

color_list = [] # 定义一个列表
for i in range(len(y)):
    c = color[i] #  选择颜色
    color_list.append([c] * len(x)) # 把颜色放入列表,并乘以x轴长度,以便每个柱形图都有颜色
color_list = np.asarray(color_list) # 将输入转为矩阵格式

xx_flat, yy_flat, acc_flat, color_flat = xx.ravel(), yy.ravel(), acc.T.ravel(), color_list.ravel() #  #ravel()方法将数组维度拉成一维数组

# 画布
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
# 绘制3D柱形图
ax.bar3d(xx_flat - 0.5, # 中心在刻度线
         yy_flat - 0.5,
         0,
         1, 1, 
         acc_flat,
    color=color_flat,  # 颜色
    edgecolor="black",  # 黑色描边
    shade=True)  # 加阴影
plt.show()

使用matplotlib绘制3D图表和统计地图_第6张图片


np.meshgrid()函数的补充

# X, Y = np.meshgrid(x, y) 代表的是将x中每一个数据和y中每一个数据组合生成很多点,然后将这些点的x坐标放入到X中,y坐标放入Y中,并且相应位置是对应的


# 如:
x = [1, 2, 3, 4]
y = [7, 8, 9]
   
# x和y中的每一个元素组合生成
[[[1, 7], [2, 7], [3, 7], [4, 7]],
 [[1, 8], [2, 8], [3, 8], [4, 8]],
 [[1, 9], [2, 9], [3, 9], [4, 9]]]
 
# 然后
# 再分别放入X和Y中
X = [[1, 2, 3, 4],
	 [1, 2, 3, 4],
	 [1, 2, 3, 4]]

Y = [[7, 7, 7, 7],
	 [8, 8, 8, 8],
	 [9, 9, 9, 9],]

# 例子
In [1]: import numpy as np

In [2]: import matplotlib.pyplot as plt

In [3]: x = np.linspace(1, 4, 4)

In [4]: x
Out[4]: array([1., 2., 3., 4.])

In [5]: y = np.linspace(7, 9, 3)

In [6]: y
Out[6]: array([7., 8., 9.])

In [7]: X, Y = np.meshgrid(x, y)

In [8]: X
Out[8]: 
array([[1., 2., 3., 4.],
       [1., 2., 3., 4.],
       [1., 2., 3., 4.]])

In [9]: Y
Out[9]: 
array([[7., 7., 7., 7.],
       [8., 8., 8., 8.],
       [9., 9., 9., 9.]])


使用animation制作动图

# FuncAnimation类
FuncAnimation(fig, # 表示动画所在的画布
              func, # 表示每帧动画调用的函数
              frames, # 表示动画的长度(一次动画包含的帧数)
              init_func, # 表示用于开始绘制帧的函数,它会在第一帧动画之前调用一次。若未设置该参数,则程序将使用frames序列中第一项的绘图结果
              fargs, # 表示传递给func函数的其他参数
              interval, # 表示更新动画的频率,以毫秒为单位,默认为200
              blit, # 表示是否更新所有的点,默认为False。官方推荐将blit参数设为True,但建议macOS用户将blit参数设为False,否则将无法显示动画
              )
  • 例子1

  • # 以qt5为图形界面后端
    %matplotlib qt5
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.animation import FuncAnimation    # 导入动画FuncAnimation类
    # 数据
    x = np.arange(0, 2 * np.pi, 0.01)
    # 画布
    fig, ax = plt.subplots()
    # 绘图
    line, = ax.plot(x, np.sin(x))
    # 定义每帧动画调用的函数 
    def animate(i):
        line.set_ydata(np.sin(x + i / 10.0))
        return line
    # 定义初始化帧的函数
    def init():
        line.set_ydata(np.sin(x))
        return line
    ani = FuncAnimation(fig=fig, # 画布
                        func=animate, # 每帧动画调用的函数
                        frames=100,  # 一次动画包含的帧数
                        init_func=init, # 用于开始绘制帧的函数,它会在第一帧动画之前调用一次。
                        interval=20, # 更新动画的频率,以毫秒为单位
                        blit=False # 是否更新所有的点,默认为False。
                       )
    plt.show()

    使用matplotlib绘制3D图表和统计地图_第7张图片

  •  例子2

  • # 案例2:点击鼠标左键暂停/继续动画
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    
    fig, ax = plt.subplots()
    # 构造空线条
    line, = ax.plot([], [])
    # 构造线条数据
    n = 50
    x = np.arange(n)
    y = np.sin(x)
    # 设置坐标轴刻度范围
    ax.set_ylim(-1.1, 1.1)
    ax.set_xlim(0, n)
    
    
    # 控制每帧画面如何绘制
    def update(i):
        line.set_data(x[:i], y[:i])
        return line,
    
    ani = animation.FuncAnimation(fig, update, n, interval=10,)
    
    # 事件处理
    paused = False
    
    def toggle_pause(event):
        global paused
        if paused:
            ani.resume()
        else:
            ani.pause()
        paused = not paused
    
    fig.canvas.mpl_connect('button_press_event', toggle_pause)
    
    plt.show()

    使用matplotlib绘制3D图表和统计地图_第8张图片



使用basemap绘制统计地图

'''
安装basemap
cmd窗口命令行安装
pip install basemap
安装完成后,在python里输入以下代码:
from mpl_toolkits.basemap import Basemap
无报错,则成功
'''


# 使用basemap
# 以下是常用参数
Basemap(llcrnrlon=None,llcrnrlat=None, # 表示地图投影区域左下角的经度或纬度
        urcrnrlon=None,urcrnrlat=None, # 表示地图投影区域右上角的经度或纬度
        lon_0=None,lat_0=None, # 表示所需地图投影区域中心的经度或纬度
        width=None,height=None, # 表示所需地图投影区域的宽度和高度
        rsphere=None, # 表示投影中使用的球体的半径
        resolution=None, # 表示包括海岸线、湖泊等的分辨率,可以取值为'c'(粗略。默认值)、'l'(低)、'i'(中级)、'h'(高)、'f'(完整)或None。
        # 若要使用shapefile(一种用于存储地理要素的几何位置和属性信息的格式)文件,则可以将resolution参数设为None,这种方式无须加载任何数据,且会极大提高程序的性能
        area_thresh=None, # 表示不会绘制海岸线或湖泊的阈值
        anchor='C', # 表示地图置于绘图区域的方式,默认为C,表示地图居中
        projection='cyl' # 表示地图投影的类型,默认值为cyl
        )

实例:美国部分城镇人口分布(basemap)

# 03_twinkling_stars_in_3d
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 创建 Basemap 对象
map = Basemap(projection='stere', # 立体影像投影
              lat_0=90, lon_0=-105, # 地图投影区域中心的经度或纬度
              llcrnrlat=23.41, llcrnrlon=-118.67, # 地图投影区域左下角的经度或纬度
              urcrnrlat=45.44, urcrnrlon=-64.52, # 地图投影区域右上角的经度或纬度
              rsphere=6371200, #  投影中使用的球体的半径
              resolution='l',  # 表示包括海岸线、湖泊低的分辨率
              area_thresh=10000 # 表示不会绘制海岸线或湖泊的阈值
             )
map.drawmapboundary()     # 绘制地图投影周围边界
map.drawstates()          # 绘制州界
map.drawcoastlines()      # 绘制海岸线
map.drawcountries()       # 绘制国家边界
# 绘制纬线
parallels = np.arange(0., 90, 10.)
map.drawparallels(parallels, labels=[1, 0, 0, 0], fontsize=10)
# 绘制经线
meridians = np.arange(-110., -60., 10.)
map.drawmeridians(meridians, labels=[0, 0, 0, 1], fontsize=10)
# 读取文件数据
posi = pd.read_csv("第七章/2014_us_cities.csv")
# 从3228组城市数据中选择500 组数据
lat = np.array(posi["lat"][0:500])               # 获取纬度值
lon = np.array(posi["lon"][0:500])               # 获取经度值
pop = np.array(posi["pop"][0:500], dtype=float)  # 获取人口数
# 气泡图的气泡大小
size = (pop / np.max(pop)) * 1000 
x, y = map(lon, lat)
map.scatter(x, y, s=size)
plt.title('2014年美国部分城镇的人口分布情况')
plt.show()

使用matplotlib绘制3D图表和统计地图_第9张图片


实例1:三维空间的星星(3D散点图)

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 生成测试数据
x = np.random.randint(0, 40, 30)
y = np.random.randint(0, 40, 30)
z = np.random.randint(0, 40, 30)
# 创建三维坐标系的绘图区域, 并在该区域中绘制3D散点图
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for xx, yy, zz in zip(x, y, z):
    # 简单判断逻辑,给每个范围的星星赋颜色
    color = 'y'
    if 10 < zz < 20:
        color = '#C71585'
    elif zz >= 20:
        color = '#008B8B'
    ax.scatter(xx, yy, zz, c=color, marker='*',
               s=160,
               linewidth=1, # 线型宽度
               edgecolor='black' # 边缘颜色
              )
# 设置轴名称和标题
ax.set_xlabel('x轴')
ax.set_ylabel('y轴')
ax.set_zlabel('z轴')
ax.set_title('3D散点图', fontproperties='simhei', # 字体样式
             fontsize=14 # 字体大小
            ) 
plt.tight_layout() # 使图形更加紧凑
plt.show()

使用matplotlib绘制3D图表和统计地图_第10张图片


实例2:三维空间闪烁的星星(3D动图)

# 02_twinkling_stars_in_3d
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 生成测试数据
xx = np.array([13, 5, 25, 13, 9, 19, 3, 39, 13, 27])
yy = np.array([4, 38, 16, 26, 7, 19, 28, 10, 17, 18])
zz = np.array([7, 19, 6, 12, 25, 19, 23, 25, 10, 15])
# 画布和创建Axes3D对象类
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 绘制初始的3D散点图
star = ax.scatter(xx, yy, zz, # 数据
                  c='#C71585', # 颜色
                  marker='*', # 标记类型
                  s=160,  # 标记大小
                  linewidth=1, # 线型宽度
                  edgecolor='black' # 边缘颜色
                 )
# 定义每帧动画调用的函数
def animate(i):
    if i % 2:
        color = '#C71585'
    else:
        color = 'white'
    next_star = ax.scatter(xx, yy, zz, c=color, marker='*', s = 160, linewidth=1, edgecolor='black')
    return next_star
# 定义初始化帧的函数
def init():
    return star # 返回初始的3D散点图
ani = FuncAnimation(fig=fig, # 画布
                    func=animate, # 每帧动画调用
                    frames=None,  # 一次动画包含的帧数
                    init_func =init, # 用于开始绘制帧的函数,它会在第一帧动画之前调用一次。
                    interval=1000, # 更新动画的频率,以毫秒为单位
                    blit=False # 是否更新所有的点,默认为False。
                   )
# 设置轴名称和标题
ax.set_xlabel('x轴')
ax.set_ylabel('y轴')
ax.set_zlabel('z轴')
ax.set_title('3D散点图', fontproperties='simhei', fontsize=14)
plt.tight_layout() # 使图形更加紧凑
plt.show()

使用matplotlib绘制3D图表和统计地图_第11张图片

 


编程题(动点)

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation # 指定渲染环境
%matplotlib auto 
# 自动
# 设置画布
fig = plt.figure(figsize=(10,6))
# 设置x,y参数
x = np.linspace(0, 2*np.pi, 256)
y = np.sin(x)
# 定义方法
def point(self):
    points.set_data(x[self], y[self]) # x[self], y[self] 表示x,y的数据
    text.set_text("x=%.3f,y=%.3f"%(x[self], y[self])) # 传入x,y的数据,保留三位小数
    return points, text # Line2D(_line1)  #Text(4, 1, 'x=4.066,y=-0.798')
# 绘制曲线图
plt.plot(x, y)
# 绘制动点
points,= plt.plot(x[0], y[0], # 初始点
                  "or"
                  )
text = plt.text(4, 1, # 文本注释位置
                '',
                fontsize=14
               ) # 添加文本注释
ani = animation.FuncAnimation(fig, # 画布
                              point, 
                              np.arange(0, 256),
                              interval=100, # 更新动画的频率,以毫秒为单位
                              blit=True # 是否更新所有的点,默认为False。
                             )
plt.show()

使用matplotlib绘制3D图表和统计地图_第12张图片


总结

本文主要使用matplotlib相关库绘制3D图表和统计地图,以望多加练习!

你可能感兴趣的:(python,可视化,matplotlib,matplotlib,3d,数据可视化,python)