Python 如何在matplotlib.axes.axes.stem plot中显示时间线?
我正在做一个Python 如何在matplotlib.axes.axes.stem plot中显示时间线?,python,matplotlib,Python,Matplotlib,我正在做一个matplotlib.axes.axes.stem图形,其中x轴是显示日期的日期线。我的一些数据出现在特定日期。而在其他日子,它没有数据(因为我的数据中不存在这样的信息) 问题1:我如何制作一个时间轴干图来显示我的数据,包括没有数据的天数?这可能吗?是否有某种方法可以自动缩放数据x轴的外观来处理这种情况 下面是一个名为test.txt的示例数据文件和我的python脚本,用于读取数据以显示时间轴干图,供您参考。下面也给出了此脚本的输出 问题2.演示问题。如何在每个注释处显示“-”符号
matplotlib.axes.axes.stem
图形,其中x轴是显示日期的日期线。我的一些数据出现在特定日期。而在其他日子,它没有数据(因为我的数据中不存在这样的信息)
问题1:我如何制作一个时间轴干图来显示我的数据,包括没有数据的天数?这可能吗?是否有某种方法可以自动缩放数据x轴的外观来处理这种情况
下面是一个名为test.txt
的示例数据文件和我的python脚本,用于读取数据以显示时间轴干图,供您参考。下面也给出了此脚本的输出
问题2.演示问题。如何在每个注释处显示“-”符号?另外,如何将注释旋转30度
test.txt
No. Date
1 23/01/2020
2 24/01/2020
3 24/01/2020
4 26/01/2020
5 27/01/2020
6 28/01/2020
7 29/01/2020
8 29/01/2020
9 30/01/2020
10 30/01/2020
11 31/01/2020
12 31/01/2020
13 01/02/2020
14 01/02/2020
15 04/02/2020
16 04/02/2020
17 04/02/2020
18 05/02/2020
19 05/02/2020
20 05/02/2020
21 06/02/2020
22 07/02/2020
23 07/02/2020
24 07/02/2020
25 08/02/2020
26 08/02/2020
27 08/02/2020
28 08/02/2020
29 08/02/2020
30 09/02/2020
31 10/02/2020
32 10/02/2020
33 11/02/2020
34 11/02/2020
38 13/02/2020
39 13/02/2020
40 13/02/2020
41 13/02/2020
42 13/02/2020
43 13/02/2020
44 14/02/2020
45 14/02/2020
46 14/02/2020
47 14/02/2020
48 14/02/2020
49 14/02/2020
50 15/02/2020
51 15/02/2020
52 15/02/2020
53 15/02/2020
54 15/02/2020
57 18/02/2020
58 18/02/2020
59 18/02/2020
60 19/02/2020
61 21/02/2020
stem_plot.py
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from datetime import datetime
from pathlib import Path
#########################
#### DATA EXTRACTION ####
#########################
source = Path('./test.txt')
with source.open() as f:
lines = f.readlines()
#print( lines )
# Store source data in dictionary with date shown as mm-dd.
data={}
for line in lines[1:]:
case, cdate = line.strip().split()
cdate = datetime.strptime(cdate, "%d/%m/%Y").strftime('%m-%d')
data[case] = cdate
print( f'\ndata = {data}' )
# Collate data's y-axis for each date, i.e. history
history2={}
cdates = list(data.values())
sorted_dates = sorted( set( cdates ) )
for i in sorted_dates:
cases=[]
for case, date in data.items():
if i == date:
cases.append(case)
#print( i, cases)
history2[i] = cases
print( f'\nhistory2 = {history2}')
###########################
#### DATA PRESENTATION ####
###########################
# Create figure and plot a stem plot with the date
fig, ax = plt.subplots(figsize=(8.8, 5), constrained_layout=True)
ax.set(title="Test")
labels=list( history2.values() ) # For annotation
yy = [ len(i) for i in labels ] # y-axis
xx = list(history2.keys()) # x-axis
markerline, stemline, baseline = ax.stem(
xx, yy, linefmt="C1:", basefmt="k-", use_line_collection=True)
plt.setp(markerline, marker="None" )
# annotate stem lines
for ann_x, label in list(history2.items()):
print(ann_x, label)
each_count=1
for each in label:
ax.annotate( each, xy=(ann_x, each_count), xycoords='data')
each_count += 1
#print(f'each_count = {each_count}' )
# format xaxis
plt.setp( ax.get_xticklabels(), rotation=30 )
# remove top and right spines
for spine in ["top", "right"]:
ax.spines[spine].set_visible(False)
# show axis name
ax.get_yaxis().set_label_text(label='Y-axis')
ax.get_xaxis().set_label_text(label='X-axis')
plt.show()
电流输出:
关于你的第一个问题。基本上,你可以列出你正在使用的日期和正在使用的日期之间的所有日期。因此,请在代码开头添加以下内容:
import pandas as pd
alldays = pd.date_range(start="20200123",
end="20200221",
normalize=True)
dates = []
for i in alldays:
dates.append(f"{i.month:02}-{i.day:02}")
它的作用是获取两个日期之间的数据范围,并将该范围转换为一个月-日字符串列表
然后修改这部分代码,如下所示:
# Collate data's y-axis for each date, i.e. history
history2={}
cdates = list(data.values())
sorted_dates = sorted( set( cdates ) )
for i in dates: # This is the only change!
cases=[]
for case, date in data.items():
if i == date:
cases.append(case)
#print( i, cases)
history2[i] = cases
这一变化将给你带来:
关于第二个问题,请将代码更改为:
# annotate stem lines
for ann_x, label in list(history2.items()):
print(ann_x, label)
each_count=1
for each in label:
ax.annotate(f"--{each}", xy=(ann_x, each_count), xycoords='data', rotation=30)
each_count += 1
我刚刚更改了ax.annotate
行。这两项改变是:
kwargs
,它们是添加@SinanKurmus对我的第一个问题的回答: 解决方案1: 对于给定数据的整个历史记录,可以使用matplotlib的方法,即and、and和python,获得具有每日间隔的时间轴。这里可以避免使用熊猫 首先,将时间轴的开始和结束日期表示为python datetime对象。注意,您需要在结束日期后再添加一天,否则将不包括上一个日期的数据。接下来,使用python的
datetime.timedelta
对象使用1天作为时间间隔。接下来,将它们提供给将返回NumPy数组的matplotlib.date.drange
方法。Matplotlib的num2date方法依次将其转换回python datetime对象
def get_time_axis( data ):
start = datetime.strptime(min(data.values()), "%Y-%m-%d")
end = datetime.strptime(max(data.values()), "%Y-%m-%d") + timedelta(days=1)
delta = timedelta(days=1)
time_axis_md = mdates.drange( start, end, delta )
time_axis_py = mdates.num2date( time_axis_md, tz=None ) # Add tz when required
return time_axis_py
解决方案2:
显然,Matplotlib也有一个常见问题解答。我在下面包含了他们的示例代码示例
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import matplotlib.ticker as ticker
r = mlab.csv2rec('../data/aapl.csv')
r.sort()
r = r[-30:] # get the last 30 days
N = len(r)
ind = np.arange(N) # the evenly spaced plot indices
def format_date(x, pos=None):
thisind = np.clip(int(x+0.5), 0, N-1)
return r.date[thisind].strftime('%Y-%m-%d')
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(ind, r.adj_close, 'o-')
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
fig.autofmt_xdate()
plt.show()
你能把你目前掌握的密码发出去吗?(还有,输出的图像。)@MateenUlhaq我已经提供了您要求的信息。您是否必须使用文本文件并使用字典绘图?“可以用熊猫之类的东西吗?”SinanKurmus肯定。更重要的是,我需要有关matplotlib部分的建议