最近需要做个文献分类汇总,老师要求要用三维散点图来画。中间还是有一些困难的,稍微记录下。
1.用python读取excel整理的数据,使用的是openpyxl库
方法比较简单,考虑到后续的标签问题,我直接把数据全部用数字代替,后续再用中文替换三维散点图的坐标轴数字。
具体代码如下:
import openpyxl
workbook = openpyxl.load_workbook("Data/2.xlsx")
sheet = workbook["Sheet1"]
# rows 按照行获取表单中所有的格子,每一行的数据放到一个元祖中
res = list(sheet.rows)
# 获取excel表格中的第一行的数据,作为字典的key==》生成一个list列表
title = [i.value for i in res[0]]
# 作为每个字典的容器
cases = []
# 遍历234行
for item in res[1:]:
# 获取每行的数据
dataline = [i.value for i in item]
# 把遍历的每行数据与第一行title数据打包成字典
dicline = dict(zip(title, dataline))
cases.append(dicline)
years=[]
for i in cases:
i =int(i['年份'])
years.append(i)
'''
编号如下:
1 谷类作物:小麦、玉米、水稻 2 5 8
2 豆类作物:豌豆、豆角、蚕豆、大豆 1 4 9 11
3 蔬菜作物:青菜、菠菜、油菜、甘蓝、甜菜 7 10 13 15
4 纤维作物:棉花 3
5 果类作物:西瓜、猕猴桃 14 16
6 饮料作物:茶叶 6
'''
envs=[]
for i in cases:
envs.append(i['实验环境'])
methods = []
'''
编号如下:
地面-数码相机:1
地面-光学相机:2
无人机-光学相机:3
无人机-数码相机:4
'''
for i in cases:
# print(i)
methods.append(i['采集方法'])
data = []
for i in range(len(years)):
for j in range(len(envs)):
if i==j:
for k in range(len(methods)):
if j==k:
t=[years[i],envs[i],methods[i]]
data.append(t)
print(data)
excel文件如下:
2.三维散点图的处理是用pyplot
三维散点图的坐标刻度要替换成中文字符
关于x,y轴,非常简单,使用ticks()方法就可以。对于z轴,比较复杂,网上搜了很多,最后采用的是set_zticklabels()。因为数据分类的原因,散点图有重叠的问题,有两种方法可以解决这个问题,透明度和抖动。透明度可以做区分,但是会显得数据量很少,所以采用的是抖动,产生抖动的点会发生透明度变化。具体代码如下:
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from test2 import data
import numpy as np
import seaborn
# 引入数据
data1 = np.array(data)
x = data1[:,0]
y = data1[:,1]
z = data1[:,2]
# 绘制散点图
fig =plt.figure()
ax = Axes3D(fig)
seaborn.regplot(data = data1,x=x ,y=y,fit_reg = False,
x_jitter = 0.4, y_jitter = 0.4,scatter_kws = {'alpha' : 2/3},color='r')
ax.scatter(x,y,z,c='r', label='122')
# 设置三个坐标轴
ax.set(xlabel='年份',ylabel='对象',zlabel='方法')
ax.set_zticklabels(['','','地面-数码相机','','地面-光学相机','','无人机-光学相机','','无人机-数码相机'])
# 设置坐标轴刻度大小
ax.tick_params(labelsize=6,length=5,grid_alpha=0)
# 不显示刻度线
ax.xaxis.set_major_locator(ticker.NullLocator())
'''
新的分类:
1 谷类作物:小麦、玉米、水稻 2 5 8
2 豆类作物:豌豆、豆角、蚕豆、大豆 1 4 9 11
3 蔬菜作物:青菜、菠菜、油菜、甘蓝、甜菜 7 10 13 15
4 纤维作物:棉花 3
5 果类作物:西瓜、猕猴桃 14 16
6 饮料作物:茶叶 6
'''
plt.xlim(0,16)
plt.ylim(0,6)
plt.xticks(np.arange(0,16,4),['2022-2019','2018-2015','2014-2011','2010-2007'],rotation='horizontal')
plt.yticks(np.arange(0,6,1),['谷类作物','豆类作物','蔬菜作物','纤维作物','果类作物','饮料作物'],rotation='vertical')
# 中文显示
plt.rcParams["font.sans-serif"]=["SimHei"] #设置中文字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
# 保存图片
plt.savefig("6.png",dpi=1200,bbox_inches ='tight')
plt.show()
最后的效果图如下:
祝好