осциллографы отсчета даты не работают правильно на линейном графике? - PullRequest
0 голосов
/ 04 февраля 2020

Я могу отобразить линейный график, используя свои данные построения, но тикеры оси X отображаются неправильно. Потому что у моего dataframe есть объект period datetimeindex, и я хочу правильно показать их вдоль оси x. Я пробовал несколько существующих постов о axis ticker, но все равно у меня не было правильного сюжета. Как это исправить? Есть идеи? спасибо

данные EDA

вот данные построения графика на основе

моя попытка :

вот моя текущая попытка:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

df = pd.read_csv('plot_data.csv', encoding='utf-8')
df.div(df.Total, axis=0).applymap(lambda x: f'{x * 100:.2f}%')
fig, ax1 = plt.subplots(figsize=(14,6))
_ = df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, ax=ax1, marker='o',ls='--')
ax1.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y))) 
ax1.xaxis.set_major_locator(mdates.DayLocator())
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d-%Y'))
plt.show()

goal

Я хочу отобразить линейный график, где на оси y должен отображаться процент, в то время как Ось X должна правильно отображать периоды по годам. В моем коде тикеры по оси X отображаются неправильно. Есть идеи?

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

Самое простое - позволить pandas сделать свое дело. Чтобы иметь даты на оси х, pandas хочет, чтобы эти даты были индексными. Просто сделайте df.set_index('quarter', inplace=True).

С таким индексом pandas установит ось х, которая выглядит как дата, но в действительности это категориальная ось (пронумерованная 0,1,2,3 ,. ..) где pandas содержит метки.

Чтобы установить проценты, используйте PercentFormatter, с параметрами, чтобы установить 100% (1, а не 100 по умолчанию) и количество десятичных знаков .

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as mtick

filename = 'plot_data.csv'
df = pd.read_csv(filename, encoding='utf-8')
df.set_index('quarter', inplace=True)
fig, ax1 = plt.subplots(figsize=(14, 6))
df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, marker='o', ls='--')
ax1.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
plt.xticks(range(len(df.index)), df.index, rotation=90)
plt.show()

resulting plot

Кроме того, вы можете преобразовать индекс в даты matplotlib и использовать форматирование и локаторы matplotlib:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as mtick

filename = 'plot_data.csv'
df = pd.read_csv(filename, encoding='utf-8')
df.quarter = [pd.to_datetime(d).date() for d in df.quarter]
df.set_index('quarter', inplace=True)
fig, ax1 = plt.subplots(figsize=(14, 6))
_ = df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, marker='o', ls='--')
ax1.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
ax1.xaxis.set_major_locator(mdates.MonthLocator(bymonthday=1, interval=3))
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d-%Y'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

plot using matplotlib dates

1 голос
/ 04 февраля 2020

Столбец quarter был преобразован в формат datetime и затем установлен в качестве индекса:

import matplotlib.dates as mdates

df = pd.read_csv('plot_data.csv', encoding='utf-8')
df['quarter'] = pd.to_datetime(df['quarter'], format='%Y-%m-%d')
df = df.set_index(df['quarter'])
df = df.sort_index()
fig, ax1 = plt.subplots(figsize=(14,6))
_ = df.drop('quarter', axis=1).div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1)
ax1.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: '{:.0%}'.format(y))) 
ax1.set_xticks(df.index)
ax1.xaxis_date()
plt.show()

enter image description here

После борьбы с matplotlib Я нашел решение, используя морского рожка.

import matplotlib.ticker as mtick
import seaborn as sns
sns.set()
df = pd.read_csv('plot_data.csv', encoding='utf-8')
df['quarter'] = pd.to_datetime(df['quarter'], format='%Y-%m-%d')
df = df.set_index(df['quarter'])
df = df.sort_index()
df_clean = df.drop('quarter', axis=1).div(df.Total, axis=0)
df_clean.drop('Total', axis=1, inplace=True)
df_us = df_clean.unstack().reset_index().copy()
df_us = df_us.rename(columns={'level_0':'Country', 0:'Percent'})
g = sns.lineplot(data=df_us, x='quarter', y='Percent', hue='Country')
g.set(xticks=df.index)
plt.xticks(rotation=30)
g.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
plt.savefig('sns.png')
plt.show()

enter image description here

...