【问题标题】:Python:How to scatterplot many years of data into one year, based on the datePython:如何根据日期将多年的数据散点为一年
【发布时间】:2017-04-06 13:25:39
【问题描述】:

我有一个 csv 文件,其中包含 13 年来每天的温度数据。现在我需要散点图这 13 年的数据。我希望 x 轴只有一年的日期(366 天),以便每个日期的值可以显示在同一日期,而无需年份。例如,August1st(87F) 的温度可以显示在同一 y 轴上,无论它是在哪一年。它是如何工作的? 数据是这样的:除了 1980 年,还有像 1981 年这样的其他年份也有 8 月 1 日。我希望他们的温度在同一个 y 轴上

【问题讨论】:

标签: python pandas matplotlib dataframe scatter-plot


【解决方案1】:

如果您使用 strptime 将日期作为日期时间读取。您可以将日期转换为一年中的某一天

Convert Year/Month/Day to Day of Year in Python

def day_of_year(date_string):
  return datetime.datetime.strptime(date_string, '%Y%m%d').timetuple().tm_yday

date_string = '19800801'

day_of_year(date_string)

>>> 214

【讨论】:

  • 哇,这很有帮助。我有另一个问题。我们如何将第一天设置为 9 月 30 日,而不是默认的 1 月 1 日?
【解决方案2】:

由于您需要散点图,一种方法是简单地使用所有数据中的同一年,然后绘制 2016 年(闰年)天数范围内的所有条目。

要让开始范围在特定日期起作用,请使用一年中的某一天来确定分割点。

这可以按如下方式完成:

from matplotlib import pyplot, dates
from datetime import datetime
import itertools
data = [
    ["STATION", "DATE", "TMAX", "TMIN"],
    ["X", "19800801", "87", "66"],
    ["X", "19800801", "87", "72"],
    ["X", "19800802", "88", "64"],
    ["X", "19800802", "86", "68"],
    ["X", "19800803", "80", "67"],
    ["X", "19800804", "89", "63"],
    ["X", "19800804", "88", "68"],
    ["X", "19800805", "89", "72"],
    ["X", "19800805", "88", "67"],
    ["X", "19800806", "85", "66"],

    # Some random data for 1984 (a leap year)
    ["X", "19840101", "77", "66"],
    ["X", "19840229", "77", "72"],
    ["X", "19840302", "78", "64"],
    ["X", "19840402", "76", "68"],
    ["X", "19840503", "73", "67"],
    ["X", "19840604", "79", "63"],
    ["X", "19840704", "78", "68"],
    ["X", "19840805", "79", "72"],
    ["X", "19840805", "78", "67"],
    ["X", "19841206", "75", "66"]]

# Date range to map data onto
d1 = datetime(year=2015, month=9, day=30)
d365 = datetime(year=2016, month=9, day=29)

yday = d1.timetuple().tm_yday   # Start day of year
pyplot.xlim(dates.date2num(d1), dates.date2num(d365))

axis_lookup = {}

# Spread data over the selected range
for s, d, tmax, tmin in data[1:]:
    dt = datetime.strptime(d, '%Y%m%d')
    year = int(dt.year)
    print(year)
    if dt.timetuple().tm_yday <  yday:
        dt = dt.replace(year=d365.year)
    else:
        dt = dt.replace(year=d1.year)

    axis_lookup[year] = axis_lookup.get(year,{'x':[],'y':[]})
    axis_lookup[year]['x'].append(dt)
    axis_lookup[year]['y'].append(tmax)


ax = pyplot.gca()
    # Convert to maplotlib format
hfmt = dates.DateFormatter('%m')
ax.xaxis.set_major_formatter(hfmt)
ax.xaxis.set_major_locator(dates.MonthLocator())
colors = itertools.cycle(["r", "b", "g"])


pyplot.xlabel('Month')
pyplot.ylabel('Temperature')

for year,axes in axis_lookup.items():
    xaxis = dates.date2num(axes['x'])
    pyplot.scatter(xaxis, axes['y'],color=next(colors), label=year,)
pyplot.tight_layout()
pyplot.legend()
pyplot.show() 

给你一个输出:

【讨论】:

  • 嗨:当我做这样的事情时:[datetime.strptime(d[4:], '%m%d') for s, d, tmax, tmin in data[1:]] ,它一直给我错误:一个月的一天超出范围。为什么会这样?我应该如何避免这种情况?
  • 我认为这是因为 1900 年没有 2 月的闰日,但我的数据中有一些年份有 2 月 29 日。那么有没有其他方法可以在我的 x 轴中包含额外的一天以使其成为 366 天而不是 365 天?谢谢!
  • 很好,在这种情况下,保留年份,然后用闰年替换它,例如2016. 我更新了脚本。
  • 哇,这确实解决了问题!我还有一个问题,我可以修改我的 xaxis 以便第一天是 9 月 30 日,而不是 1 月 1 日吗?
  • 您需要更改 d1d365 然后使用一年中的某一天来决定要映射到哪一年,例如2015 或 2016。我已经更新了脚本。
猜你喜欢
  • 2018-12-06
  • 2020-01-17
  • 2020-04-16
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
相关资源
最近更新 更多