如何从这个 nc 文件制作直方图?
How to make a histogram from this nc file?
我是一名研究助理,我最近开始学习 python 解释 netCDF 文件格式的模型输出。让我快速介绍一下我的问题的背景:
我已经使用 netCDF4 模块搜索了 netCDF 文件的某个网格区域并存储了一个时间数组,然后我使用 netCDF4 的 num2date 功能将其转换为日期列表。我在下面显示了我的代码。请注意,restrictedrange 是 nc 文件中变量的子集,rmduplicates() 未显示。
import netCDF4 as nc
import numpy as np
import matplotlib.pyplot as pyp
import matplotlib as mpl
import datetime as dtm
flor = nc.Dataset('FLOR.slp_subset1.nc','r')
times = []
timecounter = .25
for i in restrictedrange:
for j in np.nditer(i):
if(j <= 975):
times.append(timecounter)
timecounter += .25
uniquetimes = rmduplicates(times)
dates = nc.num2date(uniquetimes,'days since 0001-01-01 00:00:00','julian')
stacked_dates = []
for date in dates:
stacked_dates.append(date.replace(year=0001))
stacked_dates = mpl.dates.date2num(stacked_dates)
fig = pyp.figure()
ax = pyp.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d')
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates)
pyp.xticks(rotation='vertical')
pyp.show()
现在我有一个格式为“(y)yy-mm-dd hh:mm:ss”的日期列表。我现在想获取这些日期并按月制作直方图(可能使用 matplotlib 或任何最适合此的方法)。因此,条形图 = 频率,箱子是月份。
另外,如果我的格式不清楚,有些年份有三个数字,有些只有两个,但实际上 none 有 1.
同样,我是 python 的新手,所以我很感激任何帮助,如果这个问题格式不正确,我深表歉意,因为我从未使用过这个网站。
谢谢!
我不知道你有什么数据,但这里有一个模拟示例,说明如何制作 x 轴上 months\days 的直方图。
我只能假设您从日期时间对象列表开始,但我无法弄清楚 nc
是什么(是 matplotlib.date 模块吗?)或者什么样的时间可以恰恰在独特的时代被发现。所以通常这就是方法。
您将需要和使用这些模块。
import matplotlib as mpl
import matplotlib.pyplot as plt
import datetime
这些是我使用过的模拟日期。对于这个例子。那里只有 11 个月,所以大多数 bin 最终都会是 1。
for i in range(1, 12):
dates.append(datetime.datetime(i*5+1960, i, i, i, i, i))
[datetime.datetime(1965, 1, 1, 1, 1, 1), datetime.datetime(1970, 2, 2, 2, 2, 2), datetime.datetime(1975, 3, 3, 3, 3, 3), datetime.datetime(1980, 4, 4, 4, 4, 4), datetime.datetime(1985, 5, 5, 5, 5, 5), datetime.datetime(1990, 6, 6, 6, 6, 6), datetime.datetime(1995, 7, 7, 7, 7, 7), datetime.datetime(2000, 8, 8, 8, 8, 8), datetime.datetime(2005, 9, 9, 9, 9, 9), datetime.datetime(2010, 10, 10, 10, 10, 10), datetime.datetime(2015, 11, 11, 11, 11, 11)]
如果像上面的例子一样,你要处理不同的年份,你将不得不 "stack" 自己处理。否则,我稍后将使用的 date2num
函数将产生截然不同的数字。 To "stack" them 意味着将它们转换为就好像它们都发生在同一年一样。
stacked_dates = []
for date in dates:
stacked_dates.append( date.replace(year=2000) )
>>> stacked_dates
[datetime.datetime(2000, 1, 1, 1, 1, 1), datetime.datetime(2000, 2, 2, 2, 2, 2), datetime.datetime(2000, 3, 3, 3, 3, 3), datetime.datetime(2000, 4, 4, 4, 4, 4), datetime.datetime(2000, 5, 5, 5, 5, 5), datetime.datetime(2000, 6, 6, 6, 6, 6), datetime.datetime(2000, 7, 7, 7, 7, 7), datetime.datetime(2000, 8, 8, 8, 8, 8), datetime.datetime(2000, 9, 9, 9, 9, 9), datetime.datetime(2000, 10, 10, 10, 10, 10), datetime.datetime(2000, 11, 11, 11, 11, 11)]
好的。现在我们可以使用 date2num
函数来得到 mpl
真正理解的东西。 (顺便说一句,如果你只想绘制这些数据,你可以使用 plt.plot_dates
函数,该函数理解日期时间对象)
stacked_dates = mpl.dates.date2num(stacked_dates)
>>> stacked_dates
array([ 730120.04237269, 730152.08474537, 730182.12711806,
730214.16949074, 730245.21186343, 730277.25423611,
730308.2966088 , 730340.33898148, 730372.38135417,
730403.42372685, 730435.46609954])
好的,现在开始绘图了。 mpl
可以理解这些数字,但它会不会 自动假定它们是日期。它会将它们视为普通数字。这就是为什么我们必须告诉 x 轴它们实际上是日期。使用 major_axis_formatter
和 set_major_locator
fig = plt.figure()
ax = plt.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d') #explore other options of display
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates) #plot the damned thing
plt.xticks(rotation='vertical') #avoid overlapping numbers
#make sure you do this AFTER .hist function
plt.show()
此代码生成下图:
请注意,您有可能无法在原始图表上看到日期,因为它们会 运行 离开屏幕(此类格式可能很长,而且不适合图形)。在这种情况下,请按 "configure subplots" 按钮并调整 "bottom" 的值。在脚本中,您可以通过 plt.subplots_adjust(bottom=.3)
或其他一些值来实现。
您还应注意指定 ax.hist(stacked_dates, bins=12)
中有 12 个 bin,因为默认值为 10,并且看起来像我的图表一样时髦。
还有一个更简单的方法,尽管更少 modifiable/personofiable 等...通过使用条形图而不是直方图的可能性。了解一下 HERE 但这实际上取决于您拥有什么样的信息。如果日期很多,让 hist
函数计算 bin 高度可能比自己做更容易。
如果是其他信息,则值得考虑使用条形图。
完整的脚本应该是这样的:
import matplotlib as mpl
import matplotlib.pyplot as plt
import datetime
stacked_dates = []
for date in dates:
stacked_dates.append( date.replace(year=2000) )
stacked_dates = mpl.dates.date2num(stacked_dates)
fig = plt.figure()
ax = plt.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d')
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates)
plt.xticks(rotation='vertical')
plt.show()
我是一名研究助理,我最近开始学习 python 解释 netCDF 文件格式的模型输出。让我快速介绍一下我的问题的背景:
我已经使用 netCDF4 模块搜索了 netCDF 文件的某个网格区域并存储了一个时间数组,然后我使用 netCDF4 的 num2date 功能将其转换为日期列表。我在下面显示了我的代码。请注意,restrictedrange 是 nc 文件中变量的子集,rmduplicates() 未显示。
import netCDF4 as nc
import numpy as np
import matplotlib.pyplot as pyp
import matplotlib as mpl
import datetime as dtm
flor = nc.Dataset('FLOR.slp_subset1.nc','r')
times = []
timecounter = .25
for i in restrictedrange:
for j in np.nditer(i):
if(j <= 975):
times.append(timecounter)
timecounter += .25
uniquetimes = rmduplicates(times)
dates = nc.num2date(uniquetimes,'days since 0001-01-01 00:00:00','julian')
stacked_dates = []
for date in dates:
stacked_dates.append(date.replace(year=0001))
stacked_dates = mpl.dates.date2num(stacked_dates)
fig = pyp.figure()
ax = pyp.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d')
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates)
pyp.xticks(rotation='vertical')
pyp.show()
现在我有一个格式为“(y)yy-mm-dd hh:mm:ss”的日期列表。我现在想获取这些日期并按月制作直方图(可能使用 matplotlib 或任何最适合此的方法)。因此,条形图 = 频率,箱子是月份。 另外,如果我的格式不清楚,有些年份有三个数字,有些只有两个,但实际上 none 有 1.
同样,我是 python 的新手,所以我很感激任何帮助,如果这个问题格式不正确,我深表歉意,因为我从未使用过这个网站。
谢谢!
我不知道你有什么数据,但这里有一个模拟示例,说明如何制作 x 轴上 months\days 的直方图。
我只能假设您从日期时间对象列表开始,但我无法弄清楚 nc
是什么(是 matplotlib.date 模块吗?)或者什么样的时间可以恰恰在独特的时代被发现。所以通常这就是方法。
您将需要和使用这些模块。
import matplotlib as mpl
import matplotlib.pyplot as plt
import datetime
这些是我使用过的模拟日期。对于这个例子。那里只有 11 个月,所以大多数 bin 最终都会是 1。
for i in range(1, 12):
dates.append(datetime.datetime(i*5+1960, i, i, i, i, i))
[datetime.datetime(1965, 1, 1, 1, 1, 1), datetime.datetime(1970, 2, 2, 2, 2, 2), datetime.datetime(1975, 3, 3, 3, 3, 3), datetime.datetime(1980, 4, 4, 4, 4, 4), datetime.datetime(1985, 5, 5, 5, 5, 5), datetime.datetime(1990, 6, 6, 6, 6, 6), datetime.datetime(1995, 7, 7, 7, 7, 7), datetime.datetime(2000, 8, 8, 8, 8, 8), datetime.datetime(2005, 9, 9, 9, 9, 9), datetime.datetime(2010, 10, 10, 10, 10, 10), datetime.datetime(2015, 11, 11, 11, 11, 11)]
如果像上面的例子一样,你要处理不同的年份,你将不得不 "stack" 自己处理。否则,我稍后将使用的 date2num
函数将产生截然不同的数字。 To "stack" them 意味着将它们转换为就好像它们都发生在同一年一样。
stacked_dates = []
for date in dates:
stacked_dates.append( date.replace(year=2000) )
>>> stacked_dates
[datetime.datetime(2000, 1, 1, 1, 1, 1), datetime.datetime(2000, 2, 2, 2, 2, 2), datetime.datetime(2000, 3, 3, 3, 3, 3), datetime.datetime(2000, 4, 4, 4, 4, 4), datetime.datetime(2000, 5, 5, 5, 5, 5), datetime.datetime(2000, 6, 6, 6, 6, 6), datetime.datetime(2000, 7, 7, 7, 7, 7), datetime.datetime(2000, 8, 8, 8, 8, 8), datetime.datetime(2000, 9, 9, 9, 9, 9), datetime.datetime(2000, 10, 10, 10, 10, 10), datetime.datetime(2000, 11, 11, 11, 11, 11)]
好的。现在我们可以使用 date2num
函数来得到 mpl
真正理解的东西。 (顺便说一句,如果你只想绘制这些数据,你可以使用 plt.plot_dates
函数,该函数理解日期时间对象)
stacked_dates = mpl.dates.date2num(stacked_dates)
>>> stacked_dates
array([ 730120.04237269, 730152.08474537, 730182.12711806,
730214.16949074, 730245.21186343, 730277.25423611,
730308.2966088 , 730340.33898148, 730372.38135417,
730403.42372685, 730435.46609954])
好的,现在开始绘图了。 mpl
可以理解这些数字,但它会不会 自动假定它们是日期。它会将它们视为普通数字。这就是为什么我们必须告诉 x 轴它们实际上是日期。使用 major_axis_formatter
和 set_major_locator
fig = plt.figure()
ax = plt.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d') #explore other options of display
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates) #plot the damned thing
plt.xticks(rotation='vertical') #avoid overlapping numbers
#make sure you do this AFTER .hist function
plt.show()
此代码生成下图:
请注意,您有可能无法在原始图表上看到日期,因为它们会 运行 离开屏幕(此类格式可能很长,而且不适合图形)。在这种情况下,请按 "configure subplots" 按钮并调整 "bottom" 的值。在脚本中,您可以通过 plt.subplots_adjust(bottom=.3)
或其他一些值来实现。
您还应注意指定 ax.hist(stacked_dates, bins=12)
中有 12 个 bin,因为默认值为 10,并且看起来像我的图表一样时髦。
还有一个更简单的方法,尽管更少 modifiable/personofiable 等...通过使用条形图而不是直方图的可能性。了解一下 HERE 但这实际上取决于您拥有什么样的信息。如果日期很多,让 hist
函数计算 bin 高度可能比自己做更容易。
如果是其他信息,则值得考虑使用条形图。
完整的脚本应该是这样的:
import matplotlib as mpl
import matplotlib.pyplot as plt
import datetime
stacked_dates = []
for date in dates:
stacked_dates.append( date.replace(year=2000) )
stacked_dates = mpl.dates.date2num(stacked_dates)
fig = plt.figure()
ax = plt.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d')
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates)
plt.xticks(rotation='vertical')
plt.show()