Использование циклов для создания нескольких графиков Matplotlib с двумя осями Y - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь создать ряд графиков временных рядов, используя matplotlib для продаж различных видов фруктов и их средней цены продажи с течением времени, используя циклы. Каждый график имеет следующие идентичные характеристики:

  • Цена продажи (доходность) по левой оси Y, дневной объем продаж (ADV) по правой оси Y
  • Время (месяцы) на оси х
  • Заголовок графика с каждой серией оси Y с пометкой
  • Затенение (представляет прогноз)
  • Вертикальная контрольная линия (для представления изменения в бизнес-правилах)

Вот пример:

enter image description here

Я написал некоторый код matplotlib для создания одного графика, и он отлично работает. Теперь я хочу взять код и с помощью циклов создать один и тот же тип графиков для многих фруктовых продуктов, не создавая каждый 1 к 1, так как шаблон один и тот же, только заголовок и серия графиков на каждом графике изменяются. Код не запускается, он даже не выдает сообщение об ошибке. Как исправить?

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.style.use('seaborn-whitegrid')

# Set figure Size
fig.set_figwidth(8)
fig.set_figheight(6)

x_col = "date"
title=['Apple Metrics: ADV and Yield Over Time','Banana Metrics: ADV and Yield Over Time','Pear Metrics: ADV and Yield Over Time']
y1_col = ["apple_yld", "banana_yld", "pear_yld"]
y2_col = ["apple_adv", "banana_adv", "pear_adv"]
start_date='2015-01-01'
end_date='2021-12-01'
start_date_of_shading='2020-06-01'
end_date_of_shading='2023-05-01'


for x_col in y1_col and y2_col:

# Graph title
    fig.suptitle(title,fontsize=20)

# set x label which is common / set left y-axis label / set labelcolor and labelsize to the left Y-axis
    mygraph.set_xlabel('Date (Monthly Frequency)')
    mygraph.set_ylabel('Yield (inverted scale)', color='red',size='x-large')
    mygraph.tick_params(axis='y', labelcolor='red', labelsize='large')

# plot fruit Yield on left Y-axis; invert axis 
    mygraph.plot(df2[x_col], df2[y1_col], color='red',linewidth=3.0)
    mygraph.invert_yaxis()
    mygraph.yaxis.set_major_formatter(mpl.ticker.StrMethodFormatter('{x:,.2f}'))
    mygraph.axvline(pd.Timestamp('2019-06-01'),color='green', linestyle='--',linewidth=4.0)  

# twinx sets the same x-axis for both plots / set right y-axis label / set labelcolor and labelsize to the right Y-axis
    mygraph_1 = mygraph.twinx()
    mygraph_1.set_ylabel('ADV', color='blue', size='x-large') 
    mygraph_1.tick_params(axis='y', labelcolor='blue',labelsize='large')
    mygraph.set_xlim(['2015-01-01','2019-12-01'])

# plot fruit ADV on right Y-axis, format with comma separator  
    mygraph_1.plot(df2[x_col], df2[y2_col], color='blue',linewidth=3.0)
    mygraph_1.yaxis.set_major_formatter(mpl.ticker.StrMethodFormatter('{x:,.0f}'))
    plt.show() 

1 Ответ

0 голосов
/ 01 апреля 2020

Вы можете использовать plt.subplots(), он возвращает набор объектов фигур и осей. Оси в этом конкретном случае будут массивом формы (строки x столбцы). И вы можете назначить каждый из ваших предметов в соответствующее местоположение оси, как показано ниже:

rows=len(y1_col) #set the desired number of rows
cols=2 #set the desired number of columns

fig, ax = plt.subplots(rows, cols, figsize=(13,8),sharex=False,sharey=False) # if you want to turn off sharing axis.
row=0 #to iterate over rows/cols
col=0 #to iterate over rows/cols
for item_num in range(len(y1_col)):

    ax[row][col].plot(df2[x_col], df2[y1_col[item_num]], color='red',linewidth=3.0)
    ax[row][col].set_xlabel('Date (Monthly Frequency)')
    ax[row][col].set_ylabel('Yield (inverted scale)', color='red',size='x-large')
    ax[row][col].tick_params(axis='y', labelcolor='red', labelsize='large')
    ax[row][col].invert_yaxis()
    ax[row][col].yaxis.set_major_formatter(mpl.ticker.StrMethodFormatter('{x:,.2f}'))
    ax[row][col].axvline(pd.Timestamp('2019-06-01'),color='green', linestyle='--',linewidth=4.0)  


    axp = ax[row][col].twinx()
    axp.plot(df2[x_col], df2[y2_col[item_num]], color='blue',linewidth=3.0)
    axp.set_ylabel('ADV', color='blue', size='x-large') 
    axp.tick_params(axis='y', labelcolor='blue',labelsize='large')
    axp.set_xlim(['2015-01-01','2019-12-01'])


    col=col+1
    if col==1:
        row=row
    else:
        row=row+1
        col=0

plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...