减少标签为日期的x轴上的刻度数

时间:2018-12-20 06:40:24

标签: python matplotlib

我是matplotlib的新手,正在使用matplotlib.plot创建一个图形,x轴标记为日期,Y轴标记为数字

x = ['2018-08-17', '2018-08-20', '2018-08-21', '2018-08-22', '2018-08-23', '2018-08-24', '2018-08-27', '2018-08-28', '2018-08-29', '2018-08-30', '2018-08-31','2018-11-29', '2018-11-30', '2018-12-03', '2018-12-04', '2018-12-05']

y = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

我正在使用以下代码实时转换这些字符串日期

xdates = [dt.strptime(dstr,'%Y-%m-%d').date() for dstr in x]

将其转换为日期后,我尝试了

plt.xticks(range(0,len(xdates),2),xdates[1::2],rotation=50)

plt.plot(xdates,y)

但它无能为力。

我想在x轴上放置更少的刻度和标签。假设有15个日期,但我只希望7个或8个日期出现在x轴上。我该如何实现?

下面是用于创建趋势图的方法

def _create_trend_graph(self,element):
    if(len(self.processed_data)!=0):

        x_axis = element['X-Axis']
        y_axis = []
        plt.xticks(rotation=70)
        plt.yticks(np.arange(0, 10001,element['Range']))
        #plt.yticks(np.arange(0, 101,10))
        figure = plt.gcf()  # get current figure
        figure.set_size_inches(14, 8)
        for key in element.iterkeys():
            if key.lower().startswith("y-axis"):
                self.null_index = len(self.processed_data[element[key]])
                for index in range(len(self.processed_data[element[key]])):
                    if self.processed_data[element[key]][index] == 'Null':
                        self.null_index = index
                        break
                plt.plot(self.processed_data[x_axis][:self.null_index], list(map(float, self.processed_data[element[key]][:self.null_index])))
                y_axis = y_axis + [str(element[key])]
        #plt.legend(y_axis, prop={'size': 16})
        plt.legend(y_axis)
        plt.rcParams['font.size'] = 10.0
        plt.savefig(self.monitored_folder+element['Title'], bbox_inches='tight', dpi = 100)
        plt.close()
        self._add_image_to_body(str(element['Title']), str(element['height']), str(element['width']))
    else:
        self._create_NA()

在这里,元素['X轴']具有日期,例如

['2018-08-17','2018-08-20','2018-08-21','2018-08-22','2018-08-23','2018-08-24 ','2018-08-27','2018-08-28','2018-08-29','2018-08-30','2018-08-31','2018-11-29', '2018-11-30','2018-12-03','2018-12-04','2018-12-05']

,我们在y轴上输入数字。因此,问题实际上是我们在element ['X-Axis']中获得了大量日期,因此这只会使xaxis变得非常拥挤。而且将来的日期数可能会增加。

一种解决方案是只增加图形的大小,但这是我们要做的最后一件事。无法附加图像,因为我声誉不高。 我还能如何向您显示图像@ImportanceofbeingErnest

生成图形后,我们将其传递给以下方法

def _add_image_to_body(self,image_name,height,width):
    attachment = self.mail.Attachments.Add(self.monitored_folder+image_name+'.png')
    attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", image_name.replace(' ','_'))
    self.html += ("<img src=\"cid:" + image_name.replace(' ', '_') + '\"' + " height="+height+" width="+width+"><br><br>")

1 个答案:

答案 0 :(得分:1)

我认为您遇到的问题是matplotlib的AutoDateLocator当前每隔一个月的29号进行一次滴答,因此其标签将与下个月的第一个重叠。

import matplotlib.pyplot as plt
from datetime import datetime as dt

x = ['2018-08-17', '2018-08-20', '2018-08-21', '2018-08-22', '2018-08-23', '2018-08-24', 
     '2018-08-27', '2018-08-28', '2018-08-29', '2018-08-30', '2018-08-31','2018-11-29', 
     '2018-11-30', '2018-12-03', '2018-12-04', '2018-12-05']
y = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

xdates = [dt.strptime(dstr,'%Y-%m-%d') for dstr in x]

plt.plot(xdates,y)

plt.setp(plt.gca().get_xticklabels(), rotation=60, ha="right")
plt.tight_layout()
plt.show()

enter image description here

这可以视为错误。但这在当前的开发版本中已得到修复,因此从matplotlib 3.1开始不会再出现此问题。

一种解决方法是自己定义一个股票行情自动收录器,该代码将在每个月的第一天和第15天进行滴答。

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime as dt

x = ['2018-08-17', '2018-08-20', '2018-08-21', '2018-08-22', '2018-08-23', '2018-08-24', 
     '2018-08-27', '2018-08-28', '2018-08-29', '2018-08-30', '2018-08-31','2018-11-29', 
     '2018-11-30', '2018-12-03', '2018-12-04', '2018-12-05']
y = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

xdates = [dt.strptime(dstr,'%Y-%m-%d') for dstr in x]

plt.plot(xdates,y)

plt.gca().xaxis.set_major_locator(mdates.DayLocator((1,15)))
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
plt.setp(plt.gca().get_xticklabels(), rotation=60, ha="right")
plt.tight_layout()
plt.show()

enter image description here