简体   繁体   English

如何从我的时间序列数据中提取年份的 label 我的 x 轴?

[英]How to label my x-axis with years extracted from my time-series data?

显示行和数据类型的图表数据

I have data in this format / shape etc in a dataframe that I would like to represent in the form of a graph showing the total counts per each month.我在 dataframe 中有这种格式/形状等的数据,我想以图表的形式表示每个月的总计数。 I have resampled the data so that it shows one row for one month, and then I wrote the following code to chart it out:我对数据进行了重新采样,使其在一个月内显示一行,然后我编写了以下代码来绘制图表:

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

#Read in data & create total column
stacked_bar_data = new_df
stacked_bar_data["total"] = stacked_bar_data.var1 + stacked_bar_data.var2

#Set general plot properties
sns.set_style("whitegrid")
sns.set_context({"figure.figsize": (24, 10)})
sns.set_context("poster")

#Plot 1 - background - "total" (top) series
sns.barplot(x = stacked_bar_data.index, y = stacked_bar_data.total, color = "red")

#Plot 2 - overlay - "bottom" series
bottom_plot = sns.barplot(x = stacked_bar_data.index, y = stacked_bar_data.attended, color = "#0000A3")

topbar = plt.Rectangle((0,0),1,1,fc="red", edgecolor = 'none')
bottombar = plt.Rectangle((0,0),1,1,fc='#0000A3',  edgecolor = 'none')
l = plt.legend([bottombar, topbar], ['var1', 'var2'], loc=1, ncol = 2, prop={'size':18})
l.draw_frame(False)

#Optional code - Make plot look nicer
sns.despine(left=True)
bottom_plot.set_ylabel("Count")
# bottom_plot.set_xlabel("date")

#Set fonts to consistent 16pt size
for item in ([bottom_plot.xaxis.label, bottom_plot.yaxis.label] +
             bottom_plot.get_xticklabels() + bottom_plot.get_yticklabels()):
    item.set_fontsize(16)

# making sure our xticks is formatted correctly
plt.xticks(fontsize=20)
years = mdates.YearLocator()   # every year
months = mdates.MonthLocator()  # every month
years_fmt = mdates.DateFormatter('%Y')

bottom_plot.xaxis.set_major_locator(years)
bottom_plot.xaxis.set_major_formatter(years_fmt)
bottom_plot.xaxis.set_minor_locator(months)
plt.show()
# bottom_plot.axes.xaxis.set_visible(False)

Thing is, my chart doesn't show me the years at the bottom.问题是,我的图表没有显示底部的年份。 I believe I have all the pieces necessary to solve this problem, but for some reason I can't figure out what I'm doing wrong.我相信我拥有解决这个问题所需的所有东西,但由于某种原因,我无法弄清楚我做错了什么。

I think I'm doing something wrong with how I set up the subplots of the sns.barplot .我认为我在设置sns.barplot的子图时做错了。 Maybe I should be assigning them to fig and ax or something like that?也许我应该将它们分配给figax或类似的东西? That's how I saw it done on the matplotlib site .这就是我matplotlib网站上看到的。 I just can't managed to transfer that logic over to my example.我只是无法将该逻辑转移到我的示例中。

Any help would be most appreciated.非常感激任何的帮助。 Thanks!谢谢!

There are few things to consider.有几件事情要考虑。 First of all, please try to convert your date column ( new_df.date ) to datetime.首先,请尝试将您的日期列 ( new_df.date ) 转换为日期时间。

new_df.date = pd.to_datetime(new_df.date)

Second of all do not use this part:其次不要使用这部分:

bottom_plot.xaxis.set_major_locator(years)
bottom_plot.xaxis.set_major_formatter(years_fmt)
bottom_plot.xaxis.set_minor_locator(months)

Instead use:而是使用:

x_dates = stacked_bar_data['date'].dt.strftime('%Y').sort_values().unique()
bottom_plot.set_xticklabels(labels=x_dates, rotation=0, ha='center')

This is because seaborn re-locates the bars to integer positions.这是因为 seaborn 将钢筋重新定位到 integer 位置。 Even if we set them to be dates - Note, that you used indices explicitly.即使我们将它们设置为日期 - 请注意,您明确使用了索引。 Below is fully working example.下面是完整的工作示例。 Note - this gives you major ticks only.注意 - 这只会给你主要的蜱虫。 You'll have to work the minor ticks out.你必须解决小问题。 My comments and things I've commented out after double #.我的评论和我在双 # 之后注释掉的东西。

stacked_bar_data.date = pd.to_datetime(stacked_bar_data.date)

stacked_bar_data["total"] = stacked_bar_data.var1 + stacked_bar_data.var2

#Set general plot properties
sns.set_style("whitegrid")
sns.set_context({"figure.figsize": (14, 7)})  ## modified size :)
sns.set_context("poster")

years = mdates.YearLocator()   # every year
months = mdates.MonthLocator()  # every month
years_fmt = mdates.DateFormatter('%Y')

sns.barplot(x = stacked_bar_data.index, y = stacked_bar_data.total, color = "red")
bottom_plot = sns.barplot(x = stacked_bar_data.index, y = stacked_bar_data.attended, color = "#0000A3")

topbar = plt.Rectangle((0,0),1,1,fc="red", edgecolor = 'none')
bottombar = plt.Rectangle((0,0),1,1,fc='#0000A3',  edgecolor = 'none')
l = plt.legend([bottombar, topbar], ['var1', 'var2'], loc=1, ncol = 2, prop={'size':18})
l.draw_frame(False)

#Optional code - Make plot look nicer
sns.despine(left=True)
bottom_plot.set_ylabel("Count")
# bottom_plot.set_xlabel("date")

# making sure our xticks is formatted correctly
## plt.xticks(fontsize=20) # not needed as you change font below in the loop

## Do not use at all
## bottom_plot.xaxis.set_major_locator(years)
## bottom_plot.xaxis.set_major_formatter(years_fmt)
## bottom_plot.xaxis.set_minor_locator(months)

#Set fonts to consistent 16pt size
for item in ([bottom_plot.xaxis.label, bottom_plot.yaxis.label] +
            bottom_plot.get_xticklabels() + bottom_plot.get_yticklabels()):
    item.set_fontsize(16)

## This part is required if you want to stick to seaborn
## This is because the moment you start using seaborn it will "re-position" the bars
## at integer position rather than dates. W/o seaborn there is no such need
x_dates = stacked_bar_data['date'].dt.strftime('%Y').sort_values().unique()
bottom_plot.set_xticklabels(labels=x_dates, rotation=0, ha='center')

plt.show()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM