【问题标题】:matplotlib plots strange horizontal lines on graphmatplotlib 在图形上绘制奇怪的水平线
【发布时间】:2014-02-26 17:20:33
【问题描述】:

我使用 openpyxl 将 Excel 电子表格中的数据读取到 pandas 数据框中,称为“潮汐”。该数据集包含超过 32,000 行数据(英国潮汐时间每 15 分钟测量一次)。其中一列包含日期和时间信息(变量称为“日期时间”),另一列包含潮汐高度(称为“潮”):

我想在 x 轴上绘制日期时间,在 y 轴上绘制潮汐图:

import numpy        as np
import matplotlib       as mpl
import matplotlib.pyplot    as plt
import pandas       as pd
import openpyxl
import datetime     as dt
from matplotlib.dates import date2num

<-- Data imported from Excel spreadsheet into DataFrame using openpyxl. -->
<-- Code omitted for ease of reading.                                   -->

# Convert datatime variable to datetime64 format:
tides['datetime'] = pd.to_datetime(tides['datetime'])

# Plot figure of 'datetime' vs 'tide':
fig = plt.figure()
ax_tides = fig.add_subplot(1,1,1)
ax_tides.plot_date(date2num(phj_tides['datetime']),phj_tides['tide'],'-',xdate=True,label='Tides 2011',linewidth=0.5)

min_datetime = dt.datetime.strptime('01/01/2011 00:00:00',"%d/%m/%Y %H:%M:%S")
max_datetime = dt.datetime.strptime('03/01/2011 23:59:45',"%d/%m/%Y %H:%M:%S")
ax_tides.set_xlim( [min_datetime, max_datetime] )

plt.show()

该图仅显示前几天的数据。然而,就在这一天的变化中,奇怪的事情发生了;在第 1 天的最后一个点之后,该线向右消失,然后返回绘制第二天的第一个点 - 但数据在 y 轴上绘制不正确。这发生在整个数据集中。打印输出显示数据似乎正常。

    number            datetime   tide
0        1 2011-01-01 00:00:00  4.296
1        2 2011-01-01 00:15:00  4.024
2        3 2011-01-01 00:30:00  3.768
3        4 2011-01-01 00:45:00  3.521
4        5 2011-01-01 01:00:00  3.292
5        6 2011-01-01 01:15:00  3.081
6        7 2011-01-01 01:30:00  2.887
7        8 2011-01-01 01:45:00  2.718
8        9 2011-01-01 02:00:00  2.577
9       10 2011-01-01 02:15:00  2.470
10      11 2011-01-01 02:30:00  2.403
11      12 2011-01-01 02:45:00  2.389
12      13 2011-01-01 03:00:00  2.417
13      14 2011-01-01 03:15:00  2.492
14      15 2011-01-01 03:30:00  2.611
15      16 2011-01-01 03:45:00  2.785
16      17 2011-01-01 04:00:00  3.020
17      18 2011-01-01 04:15:00  3.314
18      19 2011-01-01 04:30:00  3.665
19      20 2011-01-01 04:45:00  4.059
20      21 2011-01-01 05:00:00  4.483

[21 rows x 3 columns]
     number            datetime   tide
90       91 2011-01-01 22:30:00  7.329
91       92 2011-01-01 22:45:00  7.014
92       93 2011-01-01 23:00:00  6.690
93       94 2011-01-01 23:15:00  6.352
94       95 2011-01-01 23:30:00  6.016
95       96 2011-01-01 23:45:00  5.690
96       97 2011-02-01 00:00:00  5.366
97       98 2011-02-01 00:15:00  5.043
98       99 2011-02-01 00:30:00  4.729
99      100 2011-02-01 00:45:00  4.426
100     101 2011-02-01 01:00:00  4.123
101     102 2011-02-01 01:15:00  3.832
102     103 2011-02-01 01:30:00  3.562
103     104 2011-02-01 01:45:00  3.303
104     105 2011-02-01 02:00:00  3.055
105     106 2011-02-01 02:15:00  2.827
106     107 2011-02-01 02:30:00  2.620
107     108 2011-02-01 02:45:00  2.434
108     109 2011-02-01 03:00:00  2.268
109     110 2011-02-01 03:15:00  2.141
110     111 2011-02-01 03:30:00  2.060

[21 rows x 3 columns]
       number            datetime   tide
35020   35021 2011-12-31 19:00:00  5.123
35021   35022 2011-12-31 19:15:00  4.838
35022   35023 2011-12-31 19:30:00  4.551
35023   35024 2011-12-31 19:45:00  4.279
35024   35025 2011-12-31 20:00:00  4.033
35025   35026 2011-12-31 20:15:00  3.803
35026   35027 2011-12-31 20:30:00  3.617
35027   35028 2011-12-31 20:45:00  3.438
35028   35029 2011-12-31 21:00:00  3.278
35029   35030 2011-12-31 21:15:00  3.141
35030   35031 2011-12-31 21:30:00  3.019
35031   35032 2011-12-31 21:45:00  2.942
35032   35033 2011-12-31 22:00:00  2.909
35033   35034 2011-12-31 22:15:00  2.918
35034   35035 2011-12-31 22:30:00  2.923
35035   35036 2011-12-31 22:45:00  2.985
35036   35037 2011-12-31 23:00:00  3.075
35037   35038 2011-12-31 23:15:00  3.242
35038   35039 2011-12-31 23:30:00  3.442
35039   35040 2011-12-31 23:45:00  3.671

我无法解释这一点。谁能解释发生了什么,为什么会发生以及我该如何纠正?

提前致谢。

菲尔

【问题讨论】:

  • 在绘图前尝试将您的 pandas 数据系列转换为列表或 numpy 数组。
  • 并查看列表表单中的日期变化。
  • 您可以发布您的数据吗?我无法使用虚拟数据复制错误。

标签: python datetime matplotlib pandas


【解决方案1】:

哇!终于找到了答案。最初的工作流程相当复杂。我将数据存储在 Excel 电子表格中,并使用 openpyxl 从命名的单元格范围读取数据。然后将其转换为 pandas DataFrame。使用 pandas 的 .to_datetime() 函数将日期和时间变量转换为日期时间格式。最后使用 matplotlib 绘制数据。当我准备将数据发布到这个论坛(如 rauparaha 建议的那样)并将脚本缩减为基本要素时,我注意到第 1 天的数据是在 2011 年 1 月 1 日绘制的,而第 2 天的数据是在 2011 年 2 月 1 日绘制的。如果你查看原始帖子中的输出,日期是混合格式:给出的最后一个日期是“2011-12-31”(即年-月-日),但代表 2011 年 1 月 2 日的第二个日期是“2011-02-” 01'(即年-日-月)。

所以,看来我误解了 pandas .to_datetime() 函数如何解释日期时间信息。我故意没有设置 infer_datetime_format 属性(默认=False),并假设任何问题都会被标记出来。但似乎 pandas 假设日期采用月份优先格式。除非他们不是,在这种情况下,它会更改为第一天格式。我应该把它捡起来!

我已通过提供明确定义日期时间格式的字符串来更正此问题。一切又好了。

再次感谢您的建议。如有任何混淆,我们深表歉意。

干杯。

【讨论】:

    【解决方案2】:

    我无法复制您的错误,但也许我的工作虚拟代码可以帮助诊断问题。我生成了虚拟数据并使用以下代码对其进行了绘制:

    import pandas as pd
    import numpy as np
    
    ydata = np.sin(np.linspace(0, 10, num=200))
    time_index = pd.date_range(start=pd.datetime(2000, 1, 1, 0, 0), periods=200, freq=15*pd.datetools.Minute())
    df = pd.DataFrame({'tides': ydata, 'datetime': time_index})
    df.plot(x='datetime', y='tides')
    

    我的数据是这样的

                 datetime     tides
    0 2000-01-01 00:00:00  0.000000
    1 2000-01-01 00:15:00  0.050230
    2 2000-01-01 00:30:00  0.100333
    3 2000-01-01 00:45:00  0.150183
    4 2000-01-01 01:00:00  0.199654
    
    [200 rows]
    

    并生成以下图

    【讨论】:

    • 非常感谢您花时间尝试复制此问题。非常感谢。我目前不在办公室,并且远离带有数据的计算机,但我会在返回后立即发布数据。再次感谢。