Пользовательская функция в Python не будет принимать Series / iterable в качестве аргументов `bottom` для гистограммы matplotlib - PullRequest
0 голосов
/ 22 сентября 2019

Отредактировано: я строю сгруппированные столбцы из моего панды DataFrame.Код обычно работает, но когда я помещаю один и тот же код в пользовательскую функцию и пытаюсь построить столбцы между двумя конкретными датами, он возвращает ошибку.Вот коды:

import pandas as pd
import matplotlib.pyplot as plt

time_table = pd.DataFrame(data =[['2019-09-03',-1.089987,5.085],
['2019-09-04',-5.982087,-2.7],
['2019-09-05',-2.887029,57.46659545],
['2019-09-06',-5.634726,-47.45]] , columns=['Exec_date','Trade_cost', 'Closed_PnL'])
time_table['Exec_date'] = pd.to_datetime(time_table['Exec_date'] )

def between_dates(df_time , start = pd.to_datetime('09/3/2019'), finish = pd.to_datetime('09/6/2019')):
    mask = (df_time['Exec_date'] >= start ) &(df_time['Exec_date'] <= finish)
    df_time = df_time.loc[mask].copy()
    plot_it(df_time)
    return df_time

def plot_it(time_table):
    fig1=plt.figure()
    axes1 = fig1.add_axes([0.1,0.1,1,1])

    # Plots
    axes1.bar(time_table['Exec_date'], time_table['Closed_PnL'], color='0.7')
    axes1.bar(time_table['Exec_date'], time_table['Trade_cost'],bottom = time_table['Closed_PnL'],color='r')
        plt.show();


between_dates(time_table)

вышеуказанный код работает.но если я изменю дату в функции between_dates на что-то, что не покрывает все мои данные, скажем, изменим начало на 09/04/2019, это вернет эту ошибку: only size-1 arrays can be converted to Python scalars, которая, я думаю, вероятно, что-то делаетфункции не могут отправлять несколько значений для аргумента bottom.Если я уберу bottom или назначу ему одно значение, моя функция будет работать без ошибок, но график больше не будет линейчатым графиком.Чтобы решить проблему, я использую цикл построения внутри своей функции:

def plot_it(time_table):
    fig1=plt.figure()
    axes1 = fig1.add_axes([0.1,0.1,1,1])

    # Plots
    axes1.bar(time_table['Exec_date'], time_table['Closed_PnL'], color='0.7',edgecolor = 'k')
    for i in time_table.index:
        axes1.bar(time_table.loc[i,'Exec_date'], time_table.loc[i,'Trade_cost'],bottom = time_table.loc[i,'Closed_PnL'],
                  color='r')
    plt.show();

Это работает!Но не выглядит так здорово.Мне интересно, есть ли более элегантный способ написания этого кода.То, что не требует прохождения for loop и построения баров по одному.Я прочитал немного о itertools.starmap , но пока не могу заставить его работать.Вот ссылка на код на Github для тестирования.Итак, есть ли лучший способ построения этих столбцов?Ценю вашу помощь и комментарии!

...