我正在做一个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()
电流输出:
添加到@SinanKurmus对我的第一个问题的回答:
解决方案1:
可以使用matplotlib的方法,即drange和num2date以及python,获得给定数据的整个历史的具有每日间隔的时间轴。这里可以避免使用熊猫
首先,将时间轴的开始和结束日期表示为python datetime对象。注意,您需要在结束日期后再添加一天,否则将不包括上一个日期的数据。接下来,使用python的
datetime.timedelta
对象使用1天作为时间间隔。接下来,将它们提供给将返回NumPy数组的matplotlib.date.drange
方法。Matplotlib的num2date方法依次将其转换回python datetime对象解决方案2:
显然,Matplotlib还有一个关于how to skip dates where there is no data的常见问题解答。我在下面包含了他们的示例代码示例
关于你的第一个问题。基本上,你可以列出你正在使用的日期和正在使用的日期之间的所有日期。因此,请在代码开头添加以下内容:
它的作用是获取两个日期之间的数据范围,并将该范围转换为一个月-日字符串列表
然后修改这部分代码,如下所示:
这一变化将给你带来:
关于第二个问题,请将代码更改为:
我刚刚更改了
ax.annotate
行。这两项改变是:kwargs
,它们是here李>这将有望满足您的要求:
相关问题 更多 >
编程相关推荐