python-3.x - 如何使用接受一个输入并输出标量值的函数来初始化等高线图的数据?

标签 python-3.x numpy matplotlib contour scalar

注意: 由于文档字符串和包含 40 个日期时间的数组,该帖子看起来比应有的长度要长。

我有一些时间序列数据。举例来说,假设我有三个参数,每个参数由 40 个数据点组成:日期时间(由 dts 给出)、速度(由 vobs 给出)和耗时(由 els 给出),它们组合在一起通过键进入字典data_dict .

dts = np.array(['2006/01/01 02:30:04', '2006/01/01 03:30:04', '2006/01/01 03:54:04'
 ,'2006/01/01 05:30:04', '2006/01/01 06:30:04', '2006/01/01 07:30:04'
 ,'2006/01/01 08:30:04', '2006/01/01 09:30:04', '2006/01/01 10:30:04'
 ,'2006/01/01 11:30:04', '2006/01/01 12:30:04', '2006/01/01 13:30:04'
 ,'2006/01/01 14:30:04', '2006/01/01 15:30:04', '2006/01/01 16:30:04'
 ,'2006/01/01 17:30:04', '2006/01/01 18:30:04', '2006/01/01 19:30:04'
 ,'2006/01/01 20:30:04', '2006/01/01 21:30:04', '2006/01/01 21:54:05'
 ,'2006/01/01 23:30:04', '2006/01/02 00:30:04', '2006/01/02 01:30:04'
 ,'2006/01/02 02:30:04', '2006/01/02 03:30:04', '2006/01/02 04:30:04'
 ,'2006/01/02 05:30:04', '2006/01/02 06:30:04', '2006/01/02 07:30:04'
 ,'2006/01/02 08:30:04', '2006/01/02 09:30:04', '2006/01/02 10:30:04'
 ,'2006/01/02 11:30:04', '2006/01/02 12:30:04', '2006/01/02 13:30:04'
 ,'2006/01/02 14:30:04', '2006/01/02 15:30:04', '2006/01/02 16:30:04'
 ,'2006/01/02 17:30:04'])

vobs = np.array([158, 1, 496, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    , 1, 1, 823, 1, 1, 1, 1, 303, 1, 1, 1, 1, 253, 1, 1, 1, 408, 1
    , 1, 1, 1, 321])

els = np.array([i for i in range(len(vobs))])

data_dictionary = {'datetime' : dts, 'values' : vobs, 'elapsed' : els}

我有一个函数,它接受字典作为输入并输出单个标量值 type <float>type <int> 。下面给出的函数比我的实际用例更简单,仅供示例使用。

def get_z(dictionary):
    """ This function returns a scalar value. """
    return np.sum(dictionary['elapsed'] / dictionary['values'])

我想看看这个函数的输出如何随着时间间隔的变化而变化。因此,我创建了一个函数,它接受字典作为输入并输出一个新字典,该字典的数组值在输入字典中每个键的输入索引处进行切片。请注意,连续耗时可以作为索引。

def subsect(dictionary, indices):
    """ This function returns a dictionary, the array values
        of which are sliced at the input indices. """
    return {key : dictionary[key][indices] for key in list(dictionary.keys())}

要验证上述函数是否有效,可以运行包含函数 read_dictionary(...) 的 for 循环下面。

def read_dictionary(dictionary):
    """ This function prints the input dictionary as a check. """
    for key in list(dictionary.keys()):
        print(" .. KEY = {}\n{}\n".format(key, dictionary[key]))

print("\nORIGINAL DATA DICTIONARY\n")
read_dictionary(data_dictionary)

# for i in range(1, 38):
    # mod_dictionary = subsect(data_dictionary, indices=slice(i, 39, 1))
    # print("\n{}th MODIFIED DATA DICTIONARY\n".format(i))
    # read_dictionary(mod_dictionary)

我的问题是我想要一个等高线图。 x 轴将包含日期时间间隔的下限( mod_dictionary[i] 的第一个条目),而 y 轴将包含日期时间间隔的上限( mod_dictioary[i] 的最后一个条目)。通常在绘制等高线图时,会有一组 (x,y)制成网格的值 (X,Y)通过numpy.meshgrid 。由于我的实际函数(不是示例中的函数)未矢量化,因此我可以使用 X.copy().reshape(-1)并使用 (...).reshape(X.shape) reshape 我的结果。

我的确切问题是,我不知道如何使用单个字典作为输出单个标量值的函数的输入来制作不同参数的网格。有办法做到这一点吗?

最佳答案

如果我正确理解你的想法,那么这应该就是你所需要的。但是我需要以下软件包:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.mlab import griddata
import pandas as pd

首先,所需的值存储在三个列表中。我必须稍微更改 for 循环,因为在您的示例中所有上限都相同,因此不可能绘制等高线图:

lower_bounds = [];
upper_bounds = [];
z_values = [];
for j in range(1, 30):
  for i in range(0,j):
    mod_dictionary = subsect(data_dictionary, indices=slice(i, j, 1))
    lower_bounds.append(mod_dictionary['datetime'][0])
    upper_bounds.append(mod_dictionary['datetime'][-1])
    z_values.append(get_z(mod_dictionary))

然后日期时间字符串被转换为时间戳:

lower_bounds_dt = [pd.Timestamp(date).value for date in lower_bounds]
upper_bounds_dt = [pd.Timestamp(date).value for date in upper_bounds]

生成等高线图的网格:

xi = np.linspace(min(lower_bounds_dt), max(lower_bounds_dt), 100)
print(xi)
yi = np.linspace(min(upper_bounds_dt), max(upper_bounds_dt), 100)
print(yi)

使用griddata生成z值的缺失网格点。

zi = griddata(lower_bounds_dt, upper_bounds_dt, z_values, xi, yi)
print(zi)

最后你可以使用contourcontourf来生成等高线图:

fig1 = plt.figure(figsize=(10, 8))
ax1 = fig1.add_subplot(111)
ax1.contourf(xi, yi, zi)
fig1.savefig('graph.png')

由于目前生成的数据只是一个小范围(因为 for 循环中的下限和上限一起增加),结果如下所示:

Result of contourf

您可以通过更改 for 循环中跨越数据数组的方式轻松更改此设置。使用 pd.to_datetime,您还可以以您喜欢的日期时间格式显示 xy 轴。

编辑:我将完整的示例上传到 repl.it

关于python-3.x - 如何使用接受一个输入并输出标量值的函数来初始化等高线图的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50213201/

相关文章:

python - 高效计算点云的体素指数

python - Break//在matplotlib的x轴上

python - matplotlib 显示具有自定义日期格式和间隔的 x 轴

python - python3 类型转换是否输入了 input() 值?

python - 将数据框列中的数字缩放到相同的比例

python - Matplot Numpy 值错误 : setting an array element with a sequence

python - matplotlib:TeX 模式下小数点和小数点之间的空格

python - paramiko 中的代理命令

python - 列表是线程安全的吗?

python - 根据 Python 中另外两个数组的值创建数组的子集