轴上的数据不是预期的顺序

时间:2017-11-16 18:50:50

标签: python-3.x matplotlib

我试图在图表上绘制一些数据,但是如果我使用data_list,那么这一切都很糟糕。

import numpy as np
from numpy import random 
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker

data_list = [('January', 1645480), ('February', 1608476), ('March', 1557113), ('April', 1391652), ('May', 1090298), ('July', 1150535), ('August', 1125931), ('September', 1158741), ('October', 1305849), ('November', 1407438), ('December', 1501733)]
working_list = [('April', 1391652), ('August', 1125931), ('December', 1501733), ('February', 1608476), ('January', 1645480), ('July', 1150535), ('March', 1557113), ('May', 1090298), ('November', 1407438), ('October', 1305849), ('September', 1158741)]

#### GRAPHING
def create_graph(data):
    x, y = zip(*data)
    plt.plot(x,y)
    axes = plt.gca() # Get the Current Axes
    axes.get_yaxis().get_major_formatter().set_scientific(False)  # Turn off scientific 
    # Show data on Y axis points
    for i, j in zip(x,y):
        plt.annotate(str(j),xy=(i,j))
    plt.show()

def main():
## Graphing
    create_graph(working_list)

if __name__ == "__main__":
    main()

enter image description here

但如果我使用working_list,那就是正确的! (它按照列表的顺序排列。我只是试图将数据从1月到12月在X轴上显示)

enter image description here

我已经盯着这个太久了 - 每个列表中的数据看起来都是一样的,只有data_list有" 1月"首先,到12月......我不确定为什么会像它那样抛弃图表。我注意到X轴月份和Y轴上的数据是正确的 - 但是线路连接器全部关闭,正如我预期的那样......

2 个答案:

答案 0 :(得分:1)

Matplotlib目前(从2.1版开始)在轴上的类别顺序存在问题。它总是在绘图之前对类别进行排序,您无法更改该顺序。这有望在下一个版本中得到修复,但在此之前,您需要坚持在轴上绘制数值。

在这种情况下,这意味着您可以根据某个索引绘制数据,然后相应地设置ticklabes。当然你也可以使用DateTimes,但这似乎有点矫枉过正是你已经有了可用月份的清单。

import numpy as np
import matplotlib.pyplot as plt


data_list = [('January', 1645480), ('February', 1608476), ('March', 1557113), 
             ('April', 1391652), ('May', 1090298), ('July', 1150535), 
             ('August', 1125931), ('September', 1158741), ('October', 1305849), 
             ('November', 1407438), ('December', 1501733)]

#### GRAPHING
def create_graph(data):
    months, y = zip(*data)
    plt.plot(range(len(months)),y)
    axes = plt.gca() # Get the Current Axes
    axes.get_yaxis().get_major_formatter().set_scientific(False)  
    axes.set_xticks(range(len(months)))
    axes.set_xticklabels(months, rotation=45, ha="right")
    # Show data on Y axis points
    for i, j in enumerate(y):
        plt.annotate(str(j),xy=(i,j))
    plt.show()


create_graph(data_list)

enter image description here

答案 1 :(得分:1)

Matplotlib按照您提供的顺序从一个点到另一个点绘制线条。

轴上的刻度根据传递的x值的类型进行排序(例如,数量的数字,字母表的caetgories,按时间顺序排列的日期)。

如果要将这些值绘制为日期,则需要将实际日期传递给plot方法。

因此,在线之间进行读取并假设您希望x轴从1月到12月,并相应地绘制线条,这是我如何做的:

from datetime import datetime

from matplotlib import pyplot
from matplotlib import dates

raw_list = [('April', 1391652), ('August', 1125931), ('December', 1501733), ('February', 1608476), ('January', 1645480), ('July', 1150535), ('March', 1557113), ('May', 1090298), ('November', 1407438), ('October', 1305849), ('September', 1158741)]
sorted_list = sorted(working_list, key=lambda x: datetime.strptime(x[0], '%B'))

def create_graph(data):
    fig, ax = pyplot.subplots()
    _x, y = zip(*data)
    x = [datetime.strptime(month, '%B') for month in _x]
    ax.plot(x, y)

    ax.yaxis.get_major_formatter().set_scientific(False)  # Turn off scientific
    ax.xaxis.set_major_locator(dates.MonthLocator(interval=1))
    ax.xaxis.set_major_formatter(dates.DateFormatter('%B'))

    for tick in ax.xaxis.get_ticklabels():
        tick.set_rotation(45)
        tick.set_rotation_mode('anchor')
        tick.set_horizontalalignment('right')

    for i, j in zip(x,y):
        ax.annotate(str(j), xy=(i, j))
    return fig

所以create_graph(raw_list)这样做:

enter image description here

所以create_graph(sorted_list)这样做:

enter image description here