本文介绍基于Python语言,读取Excel表格数据,并基于给定的行数范围内的指定列数据,绘制多条曲线图,并动态调整图片长度的方法。
首先,我们来明确一下本文的需求。现有一个.csv
格式的Excel表格文件,其第一列为表示时间的数据,而靠后的几列,也就是下图中紫色区域内的列,则是表示对应日期的属性的数据;如下图所示。
其中,第一列是一个表示时间、循环增长的列,其数值从2023001
开始,到2023365
结束,然后会继续再从2023001
开始,以此类推;并且每一个循环中,有些日期可能会缺失,即并不是每天都有数据的。
我们现在希望,对于给定的行数起始值与结束值(已知这个起始值与结束值对应的第一列数据,肯定是一个完整的时间循环),基于表格中后面带有数据的几列(也就是上图中紫色区域内的数据),绘制曲线图;并且由于这几列数据所表示的含义不同,希望用不同颜色、不同线型来表示每一列的数据。其中,我们希望具体绘制的结果如下图所示。
可以看到,横坐标就是表示时间的数据,纵坐标就是那几列含有数据的列;此外,还需要注意,前面也提到了,时间数据是不断循环的,而每一个循环中时间的数量是不确定的。因此,我们还希望绘制出来的图片,可以根据循环中时间的数量(或者说是循环的长度),来动态调整其长度。
明确了需求,即可开始撰写代码。本文所用代码如下。
python
代码解读
复制代码
# -*- coding: utf-8 -*-
"""
Created on Wed May 15 10:34:17 2024
@author: fkxxgis
"""
import os
import pandas as pd
import matplotlib.pyplot as plt
csv_file = r"E:\04_Reconstruction\99_MODIS\Train_Model_0715_Main_Combine.csv"
pic_folder = r"E:\04_Reconstruction\99_MODIS\pic"
idx_start = 520351
idx_end = 520389
df = pd.read_csv(csv_file)
selected_data = df.iloc[idx_start : idx_end]
time = selected_data.iloc[:, 0]
time_x = range(len(time))
blue_pre = selected_data.iloc[:, 9]
blue_tru = selected_data.iloc[:, 10]
green_pre = selected_data.iloc[:, 11]
green_tru = selected_data.iloc[:, 12]
red_pre = selected_data.iloc[:, 13]
red_tru = selected_data.iloc[:, 14]
nir_pre = selected_data.iloc[:, 15]
nir_tru = selected_data.iloc[:, 16]
ndvi_pre = selected_data.iloc[:, 17]
ndvi_tru = selected_data.iloc[:, 18]
plt.figure(figsize = ((idx_end - idx_start) * 0.45, 5))
plt.plot(time_x, blue_pre, 'b-', label = "Blue Predict")
plt.plot(time_x, blue_tru, 'b--', label = "Blue Actual")
plt.plot(time_x, green_pre, '-', color = "lime", label = "Green Predict")
plt.plot(time_x, green_tru, '--', color = "lime", label = "Green Actual")
plt.plot(time_x, red_pre, 'r-', label = "Red Predict")
plt.plot(time_x, red_tru, 'r--', label = "Red Actual")
plt.plot(time_x, nir_pre, '-', color = "orange", label = "NIR Predict")
plt.plot(time_x, nir_tru, '--', color = "orange", label = "NIR Actual")
plt.plot(time_x, ndvi_pre, '-', color = "darkgreen", label = "NDVI Predict")
plt.plot(time_x, ndvi_tru, '--', color = "darkgreen", label = "NDVI Actual")
plt.rc("font", family = "Times New Roman")
plt.legend(ncol = 2)
plt.xticks(time_x, time, rotation = 45)
plt.savefig(os.path.join(pic_folder, str(idx_start) + "_" + str(idx_end)), dpi = 300, bbox_inches = "tight", pad_inches = 0.05)
plt.show()
其中,我们首先导入必要的库。os
用于处理文件路径,pandas
用于读取和处理表格文件数据,matplotlib.pyplot
用于绘制图表。
接下来,我们定义文件路径和索引范围。csv_file
表示输入.csv
格式文件的路径,pic_folder
表示输出图片的文件路径,idx_start
表示数据的起始索引,idx_end
表示数据的结束索引。
接下来,我们读取.csv
格式文件并选择指定范围的数据。df = pd.read_csv(csv_file)
表示读取.csv
格式文件并创建DataFrame,而后通过selected_data = df.iloc[idx_start : idx_end]
选择指定索引范围的数据,也就是处于指定行数内的数据;time
就是第一列数据,也就是一个循环内的时间序列,time_x
则用于显示图片的x轴刻度——之所以需要这个,是因为我这里希望用字符的形式来表示图片中x轴的刻度(如果用数字的话,那么相当于一年365
天对应的x轴长度都是固定的365
个刻度;而对于时相缺失比较多的循环,这样绘制出来的图不好看)。随后,分别提取本文开头图片中紫色框内的数据,其分别表示蓝色、绿色、红色、近红外和NDVI的预测值和实际值。
随后,即可绘制曲线图。首先,通过plt.figure(figsize = ((idx_end - idx_start) * 0.45, 5))
动态设置图片尺寸,使用plt.plot()
函数绘制每个指标的预测值和实际值;同时,设置图例、x轴刻度旋转等属性,并保存图片;最后,通过plt.show()
显示绘制的图片。
运行上述代码,即可获得本文开头第二幅图所示的图片结果。