Есть ли способ правильно составить линейный график еженедельных временных рядов в matplotlib?

#python #matplotlib

#python #matplotlib

Вопрос:

Я пытаюсь составить линейную диаграмму, которая визуализирует экспортную и сбытовую активность продукта, используя еженедельные базовые данные. По сути, я хочу использовать эти данные, чтобы увидеть, как меняется количество экспортируемых различных товаров вместе с базовыми данными за неделю. Я мог бы объединить данные для построения линейной диаграммы тенденций экспорта различных товаров для топ-5 стран, но полученный график в моей попытке не дал ожидаемого результата. Кто-нибудь может указать мне, как сделать это правильно? Есть ли какой-нибудь лучший способ создать диаграмму тренда экспорта продукта, используя matplotlib или seaborn на python? Кто-нибудь может предложить возможный лучший способ сделать это? Есть какие-нибудь мысли

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

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

url = 'https://gist.githubusercontent.com/adamFlyn/e9ad428a266eccb5dc38b4cee7084372/raw/cfcbe9cf0ed19ada6a4ea409644db7414de9c87f/sales_df.csv'
df = pd.read_csv(url)
df.drop(columns=['Unnamed: 0'], inplace=True)

df_grp = df.groupby(['weekEndingDate','country', 'commodity'])['weeklyExports'].sum().unstack().reset_index()
df_grp = df_grp .fillna(0)

for c in df_grp[['FCF_Beef', 'FCF_Pork']]:
    fig, ax = plt.subplots(figsize=(7, 4), dpi=144)
    
    df_grp_new = df_grp .groupby(['country', 'weekEndingDate'])[c].sum().unstack().fillna(0)
    df_grp_new = df_grp_new .T
    df_grp_new.drop([col for col, val in df_grp_new .sum().iteritems() if val < 1000], axis=1, inplace=True)
    for col in df_grp_new.columns:
        sns.lineplot(x='WeekEndingDate', y='weekly export', ci=None, data=df_grp_new, label=col)
    ax.relim()
    ax.autoscale_view()
    ax.xaxis.label.set_visible(False)
    plt.legend(bbox_to_anchor=(1., 1), loc='upper left')
    plt.ylabel('weekly export')
    plt.margins(x=0)
    plt.title(c)
    plt.tight_layout()
    plt.grid(True)
    plt.show()
    plt.close()
 

но эти попытки не дали ожидаемого результата. По сути, я хочу посмотреть, как еженедельный экспорт различных товаров, таких как говядина и свинина, для разных стран по еженедельным базовым временным рядам. Кто-нибудь может подсказать мне, что пошло не так в моем коде? Как я могу получить желаемый линейный график, используя приведенные выше данные? Есть какие-нибудь идеи?

желаемый результат

вот пример желаемых сюжетов (просто стиль), которые я хочу создать в своей попытке:

введите описание изображения здесь
введите описание изображения здесь

Ответ №1:

Множество способов сделать это. Если вы внесете столбец time в datetime, seaborn обработает форматирование оси для вас.

Вы можете использовать facetgrid для разделения по товару или, если вы хотите более точный контроль над отдельными графиками, построить их с помощью lineplot, фильтруя df по предшествующему товару.

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

url = 'https://gist.githubusercontent.com/adamFlyn/e9ad428a266eccb5dc38b4cee7084372/raw/cfcbe9cf0ed19ada6a4ea409644db7414de9c87f/sales_df.csv'
df = pd.read_csv(url)
df.drop(columns=['Unnamed: 0'], inplace=True)

df['weekEndingDate'] = pd.to_datetime(df['weekEndingDate'])

# sns.set(rc={'figure.figsize':(11.7,8.27)})
g = sns.FacetGrid(df, col='commodity', height=8, sharex=False, sharey=False, legend_out=True)
g.map_dataframe(sns.lineplot, x='weekEndingDate',y='weeklyExports', hue='country', ci=None)
g.add_legend()
 

Диаграмма

Комментарии:

1. можем ли мы изменить масштаб оси y, чтобы графики выглядели красиво?

2. Извините, я понял, что пропустил это, да, sharey=False должен это сделать. Я обновил ответ. У вас есть некоторые выбросы в данных, в частности, в диаграмме pork — вы можете отказаться от этого или использовать какой-либо другой метод масштабирования данных, чтобы уменьшить, насколько он далек от этого.

3. ваш подход довольно прост, это приятно. Можем ли мы уменьшить продолжительность времени, чтобы еженедельный тренд элемента экспорта был более заметен для чтения? Кроме того, можем ли мы составить график, где weeklyExport и outstandingSales для топ-3 стран? Я пытался группировать, df.groupby(['weekEndingDate','country', 'commodity'])['weeklyExports', 'outstandingSales'].sum().unstack().reset_index() но не смог создать значимый график? Не могли бы вы показать, как мы можем это сделать? Спасибо 🙂

4. Возможно, отметьте это как решенное и задайте другой вопрос.,

5. подойдет, но то, что я спрашиваю, все еще основано на этом вопросе, просто небольшая настройка, о которой я думаю. Кроме того, здесь я хочу посмотреть, насколько каждая страна чувствительна к экспорту различных товаров, так что, как вы думаете, у нас может быть лучшее решение, чем текущее? Спасибо!