Python 3.x 轴上的数据不符合预期顺序
我试图在图表上绘制一些数据,但如果我使用Python 3.x 轴上的数据不符合预期顺序,python-3.x,matplotlib,Python 3.x,Matplotlib,我试图在图表上绘制一些数据,但如果我使用数据列表,那么我这样做的时候,一切都是不可靠的 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), (
数据列表
,那么我这样做的时候,一切都是不可靠的
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()
但是如果我使用工作列表
,它是正确的!(这是列表的顺序。我只是想得到从1月到12月在X轴上显示的数据)
我已经盯着这个看了太久了——每个列表中的数据看起来都是完全相同的,只有data\u list
的第一个字母是“一月”,一直到十二月……我不知道为什么会像它那样从图表中消失。我确实注意到X轴月份和Y轴上的数据是正确的,但线路连接器完全关闭,正如我所预期的那样…Matplotlib当前(从版本2.1开始)在轴上的类别顺序上存在问题。它将始终在打印之前对类别进行排序,您没有机会更改该顺序。这有望在下一版本中得到修复,但在此之前,您需要坚持在轴上绘制数值
在这种情况下,这意味着您将根据某个索引绘制数据,然后相应地设置勾号。当然,您也可以使用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)
Matplotlib按您提供的顺序逐点绘制直线 轴上的记号根据传递的x值类型进行排序(例如,数量为数字,类别为字母,日期为时间顺序) 如果要将这些值打印为日期,则需要将实际日期传递给
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
因此创建图形(原始列表)
执行以下操作:
因此创建图(排序列表)
执行以下操作:
“一月”和“四月”只是像“猫”和“狗”一样的字符串。您需要使用适当的
datetime
对象并相应地设置x轴格式化程序谢谢!这是非常简单的调整和有意义的(…好吧,它背后的想法是这样的,我不知道为什么Matplotlib会对我的数据进行排序)。正如前面所说的,它对数据进行排序的原因是假定它是分类的。基本逻辑是,它使用numpy.unique
查找唯一的类别(在您的情况下,它们已经是唯一的,但matplotlib如何知道),并且numpy.unique
返回输入的排序版本。因此,从字母A开始的几个月是第一个。这是一个错误,将在下一版本中修复。这是一个次要的细节,但值得一提的是,在x轴上使用适当的日期和日期定位器将使刻度间隔与每个月的天数成比例。@PaulH当然,但在这样一个每月有一个数据点的图中,我确实会发现三月更接近二月而不是四月,这相当令人不安,可能看起来像是一个设计缺陷。尤其是每个月有一个这样的值可能意味着一些平均值或累积值,因此不应将其解释为该月第一个月的值(可能是月中或月末,或者只是“该月的值”)。当然,就像我说的,“较小”