使用matplotlib绘制3D图表和统计地图
2023-12-21 12:29:58
目录
使用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)
'''
官方推荐
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')
绘制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()
绘制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()
?
绘制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()
?绘制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()
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()
-
?例子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()
使用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()
实例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()
实例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()
?
编程题(动点)
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图表和统计地图,以望多加练习!
文章来源:https://blog.csdn.net/m0_56181660/article/details/132775757
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!