mplfinance icon indicating copy to clipboard operation
mplfinance copied to clipboard

how to add legend to the plot?

Open jainraje opened this issue 4 years ago • 28 comments

How to add a legend to the plots? For example, if using several moving averages it will be useful to show a legend to map moving averages to line plots.

Is clear how this is done using matplotlib but I did not see an example of how to do so using the mplfinance package.

TIA,

jainraje avatar Jun 18 '20 20:06 jainraje

Rajeev, Legends are not yet available in mplfinance. Hopefully soon (maybe a couple months or so).

In the meantime, if you want to play with matplotlib, you can try using the returnfig=True kwarg in mplfinance and attempt to display legends by having access to the Figure and Axes that mplfinance creates.

Alternatively if you would like to contribute code to mplfinance to make it easy for users to include legends, I would be happy to work together with you on getting that code correctly merged into mplfinance.

All the best. Thanks for you interest in mplfinance. --Daniel

DanielGoldfarb avatar Jun 18 '20 22:06 DanielGoldfarb

Hi Daniel, I appreciate your comments. I'll give it a try. This package seems to be going in a good direction. Can we have a side bar on how I can contribute code to the package? You can email me directly at [email protected].

All the best --Rajeev

jainraje avatar Jun 21 '20 01:06 jainraje

Plot chart to figure and axis object

    fig, axes = mpf.plot(df, type='candle', mav=mav_tuple, returnfig=True)
    # Configure chart legend and title
    axes[0].legend(mav_titles)
    axes[0].set_title(ticker)
    # Save figure to file
    fig.savefig(path_to_figure)

This does the trick thanks to the help of mr. Daniel Goldfarb.

arthurpdesimone avatar Jul 31 '20 17:07 arthurpdesimone

@arthurpdesimone Thank you for posting a specific example to help others. Much appreciated. All the best. --Daniel

DanielGoldfarb avatar Jul 31 '20 20:07 DanielGoldfarb

@arthurpdesimone Thank you for posting a specific example to help others. Much appreciated. All the best. --Daniel

Hi, I'm Youngil Koh

I think the sample code below would be helpful.

style = mpf.make_mpf_style(marketcolors=mpf.make_marketcolors(up="r", down="#0000CC",inherit=True),
                           gridcolor="gray", gridstyle="--", gridaxis="both")                    

added_plots = {"EMA112" : mpf.make_addplot(data['EMA112'].iloc[start:]),
               "EMA224" : mpf.make_addplot(data['EMA224'].iloc[start:]),
               "BBLow" : mpf.make_addplot(data['BBLow'].iloc[start:]),
               "Close" : mpf.make_addplot(data['Close'].iloc[start:])
}

fig, axes = mpf.plot(data.iloc[start:, 0:5], type="candle", style=style,
                     addplot=list(added_plots.values()),
                     volume=True,
                     returnfig=True)
                     
axes[0].legend([None]*(len(added_plots)+2))
handles = axes[0].get_legend().legendHandles
axes[0].legend(handles=handles[2:],labels=list(added_plots.keys()))

axes[0].set_ylabel("Price [KRW]")
axes[0].yaxis.set_major_formatter(StrMethodFormatter('{x:,.0f}'))
axes[2].set_ylabel("Volume [ea]")
axes[2].yaxis.set_major_formatter(StrMethodFormatter('{x:,.0f}'))

output

YoungilKoh avatar Mar 15 '22 15:03 YoungilKoh

@YoungilKoh Thank you so much! That is an excellent example! Much appreciated.

DanielGoldfarb avatar Mar 15 '22 16:03 DanielGoldfarb

@arthurpdesimone Thank you for posting a specific example to help others. Much appreciated. All the best. --Daniel

Hi, I'm Youngil Koh

I think the sample code below would be helpful.

style = mpf.make_mpf_style(marketcolors=mpf.make_marketcolors(up="r", down="#0000CC",inherit=True),
                           gridcolor="gray", gridstyle="--", gridaxis="both")                    

added_plots = {"EMA112" : mpf.make_addplot(data['EMA112'].iloc[start:]),
               "EMA224" : mpf.make_addplot(data['EMA224'].iloc[start:]),
               "BBLow" : mpf.make_addplot(data['BBLow'].iloc[start:]),
               "Close" : mpf.make_addplot(data['Close'].iloc[start:])
}

fig, axes = mpf.plot(data.iloc[start:, 0:5], type="candle", style=style,
                     addplot=list(added_plots.values()),
                     volume=True,
                     returnfig=True)
                     
axes[0].legend([None]*(len(added_plots)+2))
handles = axes[0].get_legend().legendHandles
axes[0].legend(handles=handles[2:],labels=list(added_plots.keys()))

axes[0].set_ylabel("Price [KRW]")
axes[0].yaxis.set_major_formatter(StrMethodFormatter('{x:,.0f}'))
axes[2].set_ylabel("Volume [ea]")
axes[2].yaxis.set_major_formatter(StrMethodFormatter('{x:,.0f}'))

output

Thank you for your help. You're amazing

gG8Fkpxq avatar Apr 18 '22 01:04 gG8Fkpxq

I found an issue while following @YoungilKoh 's answer (https://github.com/matplotlib/mplfinance/issues/181#issuecomment-1068141054)

It worked, but only one of the plots can display (see attachment).

I'll need help on why only one of them is showing in the legends.

I debugged it, and i think i know the issue, the legendHandles only gives one Line2D object when printed, this might be a hint that can help us find the problem

unknown

quebeh avatar May 02 '22 15:05 quebeh

I found an issue while following @YoungilKoh 's answer (#181 (comment))

It worked, but only one of the plots can display (see attachment).

I'll need help on why only one of them is showing in the legends.

I debugged it, and i think i know the issue, the legendHandles only gives one Line2D object when printed, this might be a hint that can help us find the problem

unknown

Thanks for your comments! Can you share your code related to the figures you showed me? It would be helpful for me.

YoungilKoh avatar May 02 '22 17:05 YoungilKoh

Can you share your code related to the figures you showed me?

Here's my code:

ap = [
        make_addplot(pd.DataFrame(MACD), color='r', panel=1),
        make_addplot(pd.DataFrame(Signal), color='b', panel=1)
    ]
    
    axes: List[Axes]
    fig, axes = plot(
        df, title='Graph', 
        type='candlestick', 
        style='yahoo', addplot=ap, 
        returnfig=True
    )

    axes[2].legend([None]*(len(ap)+2))
    handles = axes[2].get_legend().legendHandles
    axes[2].legend(handles=handles, labels=['MACD', 'Signal'])

Did some edits in the second call of axes[2].legend, in your example, it was supposed to be handles=handles[2:], but if i do that, it just completely removes the legends. I removed the [2:] and it worked, but still, only one is showing.

Thank you for helping.

quebeh avatar May 02 '22 23:05 quebeh

Well out of nowhere, it just got fixed, i think its a new update, i used the same method. Thanks!

quebeh avatar May 06 '22 09:05 quebeh

hi, also need labels help w mplfinance. but you guys lost me per how i could adapt my code to do labels , in a script run in powershell, and save to a file. previously working code that writes my plots to file but no labels...

ap2 = [
        mpf.make_addplot(df['SUPERTl'].tail(200), color='g'),
        mpf.make_addplot(df['SUPERTs'].tail(200), color='r'),
        mpf.make_addplot(df['PSARl'].tail(200), color='y'),
        mpf.make_addplot(df['PSARs'].tail(200), color='y'),
        mpf.make_addplot(df['stochrsi_K_ultragtx'].tail(200), color='g', panel=2),  # panel 2 specified
        mpf.make_addplot(df['stochrsi_D_ultragtx'].tail(200), color='b', panel=2),  # panel 2 specified
        mpf.make_addplot(df['MACD_6_12_9'].tail(200),  color='y', secondary_y=True, panel=3),
        mpf.make_addplot(df['MACDh_6_12_9'].tail(200), color='r', secondary_y=True, panel=3),
        mpf.make_addplot(df['MACDs_6_12_9'].tail(200), color='b', secondary_y=True, panel=3)
    ]
    mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), addplot=ap2,  style='charles', savefig=save)

i changed it to this, but get error cannot unpack non-iterable NoneType object TypeError('cannot unpack non-iterable NoneType object')

i dont understand how you could do the fig,axes part AFTER you call mpf.plot. like that would have to be before .plot() call which has the savefig= param. i do have 3 panels. candles, stock and macd. but im lost per how to get labels on the plot and save it to a file from a script. thanks. code i tried per above replies:


ap2 = {
        "SuperTrend_Long": mpf.make_addplot(df['SUPERTl'].tail(200), color='g'),
        "SuperTrend_Short": mpf.make_addplot(df['SUPERTs'].tail(200), color='r'),
        "PSAR_Long": mpf.make_addplot(df['PSARl'].tail(200), color='y'),
        "PSAR_Short": mpf.make_addplot(df['PSARs'].tail(200), color='y'),
        "stochrsi_K": mpf.make_addplot(df['stochrsi_K_ultragtx'].tail(200), color='g', panel=2),  # panel 2 specified
        "stochrsi_D": mpf.make_addplot(df['stochrsi_D_ultragtx'].tail(200), color='b', panel=2),  # panel 2 specified
        "MACD": mpf.make_addplot(df['MACD_6_12_9'].tail(200),  color='y', secondary_y=True, panel=3),
        "MACDh": mpf.make_addplot(df['MACDh_6_12_9'].tail(200), color='r', secondary_y=True, panel=3),
        "MACDs": mpf.make_addplot(df['MACDs_6_12_9'].tail(200), color='b', secondary_y=True, panel=3)
    }
   
    fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), addplot=list(ap2.values()),  style='charles', savefig=save)
    axes[0].legend([None]*(len(ap2)+2))
    handles = axes[0].get_legend().legendHandles
    axes[0].legend(handles=handles[2:], labels=list(ap2.keys()))
    # IPydisplay.Image(ourpath)
    print('createimg save file')
    fig.savefig('plots/btcplot.png')

cryptoliciousdev avatar Jun 21 '22 18:06 cryptoliciousdev

The problem, I think, is in this line of code:

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), 
                     addplot=list(ap2.values()),  style='charles', savefig=save)

change savefig to returnfig=True :

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), 
                     addplot=list(ap2.values()),  style='charles', returnfig=True)

DanielGoldfarb avatar Jun 21 '22 21:06 DanielGoldfarb

this helped BUT how do i get proper colors on other panels ....lost a whole day experimenting , no luck. thanks in advance

The problem, I think, is in this line of code:

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), 
                     addplot=list(ap2.values()),  style='charles', savefig=save)

change savefig to returnfig=True :

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), 
                     addplot=list(ap2.values()),  style='charles', returnfig=True)

ap3 = {

    "SuperTrend_Long": mpf.make_addplot(df['SUPERTl'].tail(tail_num), color='g'),
    "SuperTrend_Short": mpf.make_addplot(df['SUPERTs'].tail(tail_num), color='r'),
    "PSAR_Long": mpf.make_addplot(df['PSARl'].tail(tail_num), color='y'),
    "PSAR_Short": mpf.make_addplot(df['PSARs'].tail(tail_num), color='y'),
    "EMA_15": mpf.make_addplot(df['EMA_15'].tail(tail_num),  color='#000055'),
    "EMA_20": mpf.make_addplot(df['EMA_20'].tail(tail_num),  color='#000099'),
    "EMA_30": mpf.make_addplot(df['EMA_30'].tail(tail_num),  color='#0000CC'),
    "EMA_50": mpf.make_addplot(df['EMA_50'].tail(tail_num),  color='#005500'),
    "EMA_75": mpf.make_addplot(df['EMA_75'].tail(tail_num),  color='#00CC00'),
    "EMA_100": mpf.make_addplot(df['EMA_100'].tail(tail_num),  color='#990000'),
    "EMA_200": mpf.make_addplot(df['EMA_200'].tail(tail_num),  color='#CC0000'),
    "stochrsi_K": mpf.make_addplot(df['stochrsi_K_ultragtx'].tail(tail_num), color='g', panel=2),  # panel 2 specified
    "stochrsi_D": mpf.make_addplot(df['stochrsi_D_ultragtx'].tail(tail_num), color='b', panel=2),  # panel 2 specified
    "MACDh": mpf.make_addplot(df['MACDh_6_12_9'].tail(tail_num), color='r', secondary_y=True, panel=3),
    "MACDs": mpf.make_addplot(df['MACDs_6_12_9'].tail(tail_num), color='b', secondary_y=True, panel=3)
}
print('making axes0 legend')
fig, axes = mpf.plot(df.tail(tail_num), type='candle', volume=True,  addplot=list(ap3.values()),  style='charles',
                     returnfig=True, title=('Last '+str(tail_num)+' candles'+fname), scale_width_adjustment=dict(lines=0.25))
axes[0].legend([None]*(len(ap3)+2))
handles = axes[0].get_legend().legendHandles
axes[0].legend(handles=handles[2:], labels=list(ap3.keys()), loc='upper left', fontsize='x-small')
#axes[0].legend(loc='upper left', fontsize='x-small')
# IPydisplay.Image(ourpath)
print(axes)
axes[4].set_ylabel("MACD")
axes[6].set_ylabel("StochRSI")
print(axes)
print(len(ap3))
try:
    axes[4].legend([None]*(len(ap3)+2))

    axes[4].legend(handles=handles[2:], labels=['MACDh', 'MACDs'], loc='center left', fontsize='x-small')
except Exception as e:
    print('error making legend axis4')
    print(e)
print('making axes6 legend')
try:
    # axes[6].legend([None]*(len(ap3)+2))
    # axes[6].legend([None]*(2+2))
    #handles6 = axes[6].get_legend().legendHandles
    axes[6].legend(handles=handles[2:], labels=['stochrsi_K', 'stochrsi_D'], loc='center left', fontsize='x-small')
except Exception as e:
    print('error making legend axis6')
    print(e)
fig.savefig('plots/'+fname, dpi=300)

2022-06-23_23_00_00_UTC_BTC-USDT_1h

you see ax6 , the stochrsi subplot on the bottom....i dont understand how to reference that handles of legend should be the correct colors. its obviuosly giving the colors of the top panels first 2...but no matter what i tried n read in the docs, i couldnt find examples both ref'd panels legend and from a addplot list. thanks

cryptoliciousdev avatar Jun 23 '22 23:06 cryptoliciousdev

Have you tried using axes[7]? You have a total of 4 panels (0-3), which means 8 Axes: 0-7

Also, I'm confused by something in your code: The code appears to be putting StochRSI on panel 2, and macd on panel 3. But in the plot image StochRSI is on the bottom panel (panel 3) and MACD is just above that (panel 2).

I would also point out that the StochRSI panel has y-ticks on both the left and right, which suggests that between 'stochrsi_K' and 'stochrsi_D', one of them may be using axes[7] and the other axes[6]. If this is what you want, fine. If not, then you can code specifically secondary_y=False (or True, depending what you want), because by not specifying secondary_y at all, its default value is 'auto' which means that mplfinance may decide to put them on separate Axes.

DanielGoldfarb avatar Jun 24 '22 00:06 DanielGoldfarb

Also, one other point to keep in mind, that may have an effect:
The "charles" style puts the primary axes on the right (see y_on_right = True inside the "charles" style definition file). This means that secondary_y will be on the left. Thus Axes 0,2,4,6 have their y-values on the right, while Axes 1,3,5,7 are have their y-values on the left.

Keep in mind that if you don't specify secondary_y (thus defaulting to 'auto') then the first data plotted on each panel will go on the primary axes (0,2,4,6) while any subsequent data may be plotted on the on either the primary (0,2,4,6) or the secondary (1,3,5,7) depending on what mplfinance decides. You can force it to be on primary or secondary by specifying secondary_y=False (primary) or secondary_y=True (secondary).

DanielGoldfarb avatar Jun 24 '22 01:06 DanielGoldfarb

YES , thanks, my mistake flipping the labels and secondary_y all being true. fixed that! and i got the stochrsi colors to be correct in the legend now :D pulling into handles4 and referencing handles4 made it work!

    try:
        axes[4].legend([None]*(len(ap3)+2))
        handles4 = axes[4].get_legend().legendHandles
        axes[4].legend(handles=handles4, labels=['stochrsi_K', 'stochrsi_D'], loc='center left', fontsize='x-small')
    except Exception as e:
        print('error making legend axis4')
        print(e)

Also, one other point to keep in mind, that may have an effect: The "charles" style puts the primary axes on the right (see y_on_right = True inside the "charles" style definition file). This means that secondary_y will be on the left. Thus Axes 0,2,4,6 have their y-values on the right, while Axes 1,3,5,7 are have their y-values on the left.

Keep in mind that if you don't specify secondary_y (thus defaulting to 'auto') then the first data plotted on each panel will go on the primary axes (0,2,4,6) while any subsequent data may be plotted on the on either the primary (0,2,4,6) or the secondary (1,3,5,7) depending on what mplfinance decides. You can force it to be on primary or secondary by specifying secondary_y=False (primary) or secondary_y=True (secondary).

THANKS and hope the mulitpanel legend struggle of mine helps people 2022-06-24_01_00_00_UTC_BTC-USDT_1h .

cryptoliciousdev avatar Jun 24 '22 01:06 cryptoliciousdev

THANKS and hope the mulitpanel legend struggle of mine helps people

There is no question. Posting your struggles here definitely helps other mplfinance users.

Not only does it help them directly, but it will help them indirectly in the future, as it is my intention to implement a legends kwarg to mplfinance.plot() hopefully before the end of this year. All of the posts in this issue will certainly help guide that implementation in order to make the legends kwarg of mplfinace both as simple to use, and as flexible, as possible.

Two addition things:

  1. Looking at your last plot it appears that "MACDh" in the legend somehow picked up green instead of blue.
    I can't see why because the code is not posted, which leads me to my second item:
  2. Would you mind posting your final complete code here for all to see? That will be most helpful and very appreciated by your fellow mplfinance users.

Finally, let me just say that your plot is one of the best mplfinance plots I have ever seen! Really, excellent job! Thank you for sharing!

All the best. --Daniel

DanielGoldfarb avatar Jun 24 '22 12:06 DanielGoldfarb

def plotting_datav5(symbol, interval, frame, max_price, first_level, second_level, third_level, fourth_level, min_price):
    mc = mpf.make_marketcolors(up='g',down='r',alpha=0.5,volume={'up':'g','down':'r'})
    s  = mpf.make_mpf_style(base_mpf_style='binance',marketcolors=mc,gridstyle='')


    fig = mpf.figure(style=s,figsize=(12,9))
    ax = fig.add_subplot()
    ax.set_title(f'{symbol} {interval} Fibonnacci Seviyeleri') # ,loc='left'

    frame['max_price'] = [max_price] * len(frame)
    frame['first_level'] = [first_level] * len(frame)
    frame['second_level'] = [second_level] * len(frame)
    frame['third_level'] = [third_level] * len(frame)
    frame['fourth_level'] = [fourth_level] * len(frame)
    frame['min_price'] = [min_price] * len(frame)
    apds = {"EMA50": mpf.make_addplot(frame['EMA50'],ax=ax,color='blue'),
            "EMA144": mpf.make_addplot(frame['EMA144'],ax=ax,color='orange'),
            "max_price": mpf.make_addplot(frame['max_price'], ax=ax, linestyle='--', alpha=0.5, color='red'),
            "first_level": mpf.make_addplot(frame['first_level'], ax=ax, linestyle='--', alpha=0.5, color='orange'),
            "second_level": mpf.make_addplot(frame['second_level'], ax=ax, linestyle='--', alpha=0.5, color='aqua'),
            "third_level": mpf.make_addplot(frame['third_level'], ax=ax, linestyle='--', alpha=0.5, color='green'),
            "fourth_level": mpf.make_addplot(frame['fourth_level'], ax=ax, linestyle='--', alpha=0.5, color='blue'),
            "min_price": mpf.make_addplot(frame['min_price'], ax=ax, linestyle='--', alpha=0.5, color='purple'),
            }

    ax.legend([None] * (len(apds) + 2))
    handles = ax.get_legend().legendHandles
    ax.legend(handles=handles[2:], labels=list(apds.keys()), loc='upper left', fontsize='x-small')
    # axes[0].legend(loc='upper left', fontsize='x-small')
    mpf.plot(frame,ax=ax,type='candle',xrotation=0,addplot=list(apds.values()),tight_layout=False)

    plt.savefig('Figure_1.png',bbox_inches='tight')
    mpf.show()

This gives error:

No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.

Couldn't find what is the cause of error. Can anybody help? Ps: I can see drawing but no legends

drdoof2019 avatar Jul 29 '22 07:07 drdoof2019

with subplots it's easy👍👍

fig , ax =plt.subplots(3,1,sharex=True,figsize=(10,10),gridspec_kw= {'height_ratios':[3,2,2]})

fig.set_edgecolor('k') fig.set_linewidth(4) fig.set_facecolor('cyan') ax3 = ax[2].twinx()

p2 = [ mpf.make_addplot(data['High'],color='g',ax=ax[2]),
mpf.make_addplot(data['Low'],color='b',ax=ax[2]), mpf.make_addplot(data['macd'],ax=ax3,color='r')]

mpf.plot(data,type='candle',ax=ax[0], addplot=p2 ,style='blueskies',volume=ax[1],mav=(6,9)) fig.suptitle('AAPL')

ax[0].legend(labels=['nolegend','nolegend','mav6','mav9']) ax[2].legend(['High','Low']) ax3.legend(['MACD'],bbox_to_anchor=[0.7,0.2]) ax[2].grid(False) ax[0].set_ylabel('Price',fontsize=15,labelpad=30,color='r') ax[1].set_ylabel('Volume',fontsize=10,labelpad=35,color='r')

plt.tight_layout() plt.show()

ashraf2000shweky avatar Dec 29 '22 10:12 ashraf2000shweky

Support for legends is a very important capability for mplfinance to directly support. In the meantime, I really liked the sample code from Youngil Koh and it allowed me to succeed in my efforts to get proper legend display.

My application is a bit complex and the addplots are conditionally created. To avoid rewriting it to conform to the example code, I decided to get the labels out of the addplot data structures. Here is the resulting code snippet and function which I created for my application. It creates the legend for the main panel (panel 0) or any of the sub panels.

def plotter(someargs):
    ....
    style = mpf.make_mpf_style(gridcolor="gray", gridstyle="--", gridaxis="both", facecolor='0.98', figcolor='0.93',
                        marketcolors=mpf.make_marketcolors(volume={'up':'tab:green', 'down':'tab:red'}, vcdopcod=True))

    fig, axes = mpf.plot(df, type=ptype, volume=volume_requested, figscale=2, title=title, tight_layout=True,
                       panel_ratios=panel_ratios, addplot=ap_list, scale_width_adjustment=dict(lines=0.9, volume=0.9),
                       linecolor='black', style=style, returnfig=True)

    # add a legend to the main plot window and some subpanels
    add_legend(axes, ap_list, 0, ptype=ptype)
    for panel in legend_needed:
        add_legend(axes, ap_list, panel)
    ....


def add_legend(axes, add_plots, panel, primary_label='', ptype=None, loc='upper left'):
    labels = []

    # set label for main panel primary data series
    if panel == 0:
        if primary_label == '':
            primary_label = 'AdjOHLC' if ptype == 'ohlc' or ptype == 'candle' else 'AdjClose'
        labels.append(primary_label)

    # grab labels from the add plots attached to the specified panel
    for ap_data in [ap['data'] for ap in add_plots if ap['panel'] == panel]:
        if isinstance(ap_data, pd.Series):
            labels.append(ap_data.name)
        elif isinstance(ap_data, pd.DataFrame):
            labels += list(ap_data.columns)

    # need to use offsets to get correct ax and handles based on figure structure
    ax_offset = 2 if panel > 0 else 0
    handle_offset = 2 if ptype == 'ohlc' else 1 if ptype == 'candle' else 0

    # add the legend
    axes[panel + ax_offset].legend([None] * (len(labels) + handle_offset))
    handles = axes[panel + ax_offset].get_legend().legendHandles
    axes[panel + ax_offset].legend(handles=handles[handle_offset:], labels=labels, loc=loc)

DavidT-123 avatar May 21 '23 16:05 DavidT-123

this helped BUT how do i get proper colors on other panels ....lost a whole day experimenting , no luck. thanks in advance

The problem, I think, is in this line of code:

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), 
                     addplot=list(ap2.values()),  style='charles', savefig=save)

change savefig to returnfig=True :

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), 
                     addplot=list(ap2.values()),  style='charles', returnfig=True)

ap3 = {

    "SuperTrend_Long": mpf.make_addplot(df['SUPERTl'].tail(tail_num), color='g'),
    "SuperTrend_Short": mpf.make_addplot(df['SUPERTs'].tail(tail_num), color='r'),
    "PSAR_Long": mpf.make_addplot(df['PSARl'].tail(tail_num), color='y'),
    "PSAR_Short": mpf.make_addplot(df['PSARs'].tail(tail_num), color='y'),
    "EMA_15": mpf.make_addplot(df['EMA_15'].tail(tail_num),  color='#000055'),
    "EMA_20": mpf.make_addplot(df['EMA_20'].tail(tail_num),  color='#000099'),
    "EMA_30": mpf.make_addplot(df['EMA_30'].tail(tail_num),  color='#0000CC'),
    "EMA_50": mpf.make_addplot(df['EMA_50'].tail(tail_num),  color='#005500'),
    "EMA_75": mpf.make_addplot(df['EMA_75'].tail(tail_num),  color='#00CC00'),
    "EMA_100": mpf.make_addplot(df['EMA_100'].tail(tail_num),  color='#990000'),
    "EMA_200": mpf.make_addplot(df['EMA_200'].tail(tail_num),  color='#CC0000'),
    "stochrsi_K": mpf.make_addplot(df['stochrsi_K_ultragtx'].tail(tail_num), color='g', panel=2),  # panel 2 specified
    "stochrsi_D": mpf.make_addplot(df['stochrsi_D_ultragtx'].tail(tail_num), color='b', panel=2),  # panel 2 specified
    "MACDh": mpf.make_addplot(df['MACDh_6_12_9'].tail(tail_num), color='r', secondary_y=True, panel=3),
    "MACDs": mpf.make_addplot(df['MACDs_6_12_9'].tail(tail_num), color='b', secondary_y=True, panel=3)
}
print('making axes0 legend')
fig, axes = mpf.plot(df.tail(tail_num), type='candle', volume=True,  addplot=list(ap3.values()),  style='charles',
                     returnfig=True, title=('Last '+str(tail_num)+' candles'+fname), scale_width_adjustment=dict(lines=0.25))
axes[0].legend([None]*(len(ap3)+2))
handles = axes[0].get_legend().legendHandles
axes[0].legend(handles=handles[2:], labels=list(ap3.keys()), loc='upper left', fontsize='x-small')
#axes[0].legend(loc='upper left', fontsize='x-small')
# IPydisplay.Image(ourpath)
print(axes)
axes[4].set_ylabel("MACD")
axes[6].set_ylabel("StochRSI")
print(axes)
print(len(ap3))
try:
    axes[4].legend([None]*(len(ap3)+2))

    axes[4].legend(handles=handles[2:], labels=['MACDh', 'MACDs'], loc='center left', fontsize='x-small')
except Exception as e:
    print('error making legend axis4')
    print(e)
print('making axes6 legend')
try:
    # axes[6].legend([None]*(len(ap3)+2))
    # axes[6].legend([None]*(2+2))
    #handles6 = axes[6].get_legend().legendHandles
    axes[6].legend(handles=handles[2:], labels=['stochrsi_K', 'stochrsi_D'], loc='center left', fontsize='x-small')
except Exception as e:
    print('error making legend axis6')
    print(e)
fig.savefig('plots/'+fname, dpi=300)

2022-06-23_23_00_00_UTC_BTC-USDT_1h

you see ax6 , the stochrsi subplot on the bottom....i dont understand how to reference that handles of legend should be the correct colors. its obviuosly giving the colors of the top panels first 2...but no matter what i tried n read in the docs, i couldnt find examples both ref'd panels legend and from a addplot list. thanks

wow! How do you get the candles etc so crips in your image from the mplfinance save file? would love mine to look like this.

As an example, here's what my candles look like. not bad but it's not the view that i want and struggling to make it look crisper and larger in context of the overall saved image. also want to add the legend.

https://ibb.co/g6cVcy8

Heres the code im using to save the file but it's still not quite right: mpf.plot(data, type='candle', style='yahoo', title=title,savefig=dict(fname=savedPlotFileName,dpi=400,pad_inches=0.0), hlines=dict(hlines=[fib_62, fib_705, fib_79,fib_21, fib_295, fib_38],colors=['r','g','r','r','g','r'],linestyle='-.'), fill_between=dict(y1=minlow,y2=minhigh,where=where_values, alpha=0.5, color='g'))

Is there any updates on the LEGENDS capability within the package yet?

TraderMan999 avatar Jun 25 '23 22:06 TraderMan999

You need to get the handles from the same subplot where you are intending to define the legend. In your code you have:

handles = axes[0].get_legend().legendHandles

which you use for the main plot, but when moving on to the subplots, you did not grab the handles again from those axes...

On Jun 25, 2023, at 5:32 PM, TraderMan999 @.***> wrote:

this helped BUT how do i get proper colors on other panels ....lost a whole day experimenting , no luck. thanks in advance

The problem, I think, is in this line of code:

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), addplot=list(ap2.values()), style='charles', savefig=save) change savefig to returnfig=True :

fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), addplot=list(ap2.values()), style='charles', returnfig=True) ap3 = {

"SuperTrend_Long": mpf.make_addplot(df['SUPERTl'].tail(tail_num), color='g'),
"SuperTrend_Short": mpf.make_addplot(df['SUPERTs'].tail(tail_num), color='r'),
"PSAR_Long": mpf.make_addplot(df['PSARl'].tail(tail_num), color='y'),
"PSAR_Short": mpf.make_addplot(df['PSARs'].tail(tail_num), color='y'),
"EMA_15": mpf.make_addplot(df['EMA_15'].tail(tail_num),  color='#000055'),
"EMA_20": mpf.make_addplot(df['EMA_20'].tail(tail_num),  color='#000099'),
"EMA_30": mpf.make_addplot(df['EMA_30'].tail(tail_num),  color='#0000CC'),
"EMA_50": mpf.make_addplot(df['EMA_50'].tail(tail_num),  color='#005500'),
"EMA_75": mpf.make_addplot(df['EMA_75'].tail(tail_num),  color='#00CC00'),
"EMA_100": mpf.make_addplot(df['EMA_100'].tail(tail_num),  color='#990000'),
"EMA_200": mpf.make_addplot(df['EMA_200'].tail(tail_num),  color='#CC0000'),
"stochrsi_K": mpf.make_addplot(df['stochrsi_K_ultragtx'].tail(tail_num), color='g', panel=2),  # panel 2 specified
"stochrsi_D": mpf.make_addplot(df['stochrsi_D_ultragtx'].tail(tail_num), color='b', panel=2),  # panel 2 specified
"MACDh": mpf.make_addplot(df['MACDh_6_12_9'].tail(tail_num), color='r', secondary_y=True, panel=3),
"MACDs": mpf.make_addplot(df['MACDs_6_12_9'].tail(tail_num), color='b', secondary_y=True, panel=3)

} print('making axes0 legend') fig, axes = mpf.plot(df.tail(tail_num), type='candle', volume=True, addplot=list(ap3.values()), style='charles', returnfig=True, title=('Last '+str(tail_num)+' candles'+fname), scale_width_adjustment=dict(lines=0.25)) axes[0].legend([None]*(len(ap3)+2)) handles = axes[0].get_legend().legendHandles axes[0].legend(handles=handles[2:], labels=list(ap3.keys()), loc='upper left', fontsize='x-small') #axes[0].legend(loc='upper left', fontsize='x-small')

IPydisplay.Image(ourpath)

print(axes) axes[4].set_ylabel("MACD") axes[6].set_ylabel("StochRSI") print(axes) print(len(ap3)) try: axes[4].legend([None]*(len(ap3)+2))

axes[4].legend(handles=handles[2:], labels=['MACDh', 'MACDs'], loc='center left', fontsize='x-small')

except Exception as e: print('error making legend axis4') print(e) print('making axes6 legend') try: # axes[6].legend([None](len(ap3)+2)) # axes[6].legend([None](2+2)) #handles6 = axes[6].get_legend().legendHandles axes[6].legend(handles=handles[2:], labels=['stochrsi_K', 'stochrsi_D'], loc='center left', fontsize='x-small') except Exception as e: print('error making legend axis6') print(e) fig.savefig('plots/'+fname, dpi=300) https://user-images.githubusercontent.com/97939226/175432610-9a387d8d-42ea-465c-83b5-b688073dffa7.png you see ax6 , the stochrsi subplot on the bottom....i dont understand how to reference that handles of legend should be the correct colors. its obviuosly giving the colors of the top panels first 2...but no matter what i tried n read in the docs, i couldnt find examples both ref'd panels legend and from a addplot list. thanks

wow! How do you get the candles etc so crips in your image from the mplfinance save file? would love mine to look like this.

As an example, here's what my candles look like. not bad but it's not the view that i want and struggling to make it look crisper and larger in context of the overall saved image. also want to add the legend.

https://ibb.co/g6cVcy8 https://ibb.co/g6cVcy8 Is there any updates on the LEGENDS capability within the package yet?

— Reply to this email directly, view it on GitHub https://github.com/matplotlib/mplfinance/issues/181#issuecomment-1606290992, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD4NKOSLOV2EY6YFEQRXGELXNC4AXANCNFSM4OCESKDQ. You are receiving this because you commented.

DavidT-123 avatar Jun 26 '23 16:06 DavidT-123

You need to get the handles from the same subplot where you are intending to define the legend. In your code you have: handles = axes[0].get_legend().legendHandles which you use for the main plot, but when moving on to the subplots, you did not grab the handles again from those axes... On Jun 25, 2023, at 5:32 PM, TraderMan999 @.> wrote: this helped BUT how do i get proper colors on other panels ....lost a whole day experimenting , no luck. thanks in advance The problem, I think, is in this line of code: fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), addplot=list(ap2.values()), style='charles', savefig=save) change savefig to returnfig=True : fig, axes = mpf.plot(df.tail(200), type='candle', volume=True, mav=(26, 50, 75, 100, 150), addplot=list(ap2.values()), style='charles', returnfig=True) ap3 = { "SuperTrend_Long": mpf.make_addplot(df['SUPERTl'].tail(tail_num), color='g'), "SuperTrend_Short": mpf.make_addplot(df['SUPERTs'].tail(tail_num), color='r'), "PSAR_Long": mpf.make_addplot(df['PSARl'].tail(tail_num), color='y'), "PSAR_Short": mpf.make_addplot(df['PSARs'].tail(tail_num), color='y'), "EMA_15": mpf.make_addplot(df['EMA_15'].tail(tail_num), color='#55'), "EMA_20": mpf.make_addplot(df['EMA_20'].tail(tail_num), color='#99'), "EMA_30": mpf.make_addplot(df['EMA_30'].tail(tail_num), color='#0000CC'), "EMA_50": mpf.make_addplot(df['EMA_50'].tail(tail_num), color='#005500'), "EMA_75": mpf.make_addplot(df['EMA_75'].tail(tail_num), color='#00CC00'), "EMA_100": mpf.make_addplot(df['EMA_100'].tail(tail_num), color='#990000'), "EMA_200": mpf.make_addplot(df['EMA_200'].tail(tail_num), color='#CC0000'), "stochrsi_K": mpf.make_addplot(df['stochrsi_K_ultragtx'].tail(tail_num), color='g', panel=2), # panel 2 specified "stochrsi_D": mpf.make_addplot(df['stochrsi_D_ultragtx'].tail(tail_num), color='b', panel=2), # panel 2 specified "MACDh": mpf.make_addplot(df['MACDh_6_12_9'].tail(tail_num), color='r', secondary_y=True, panel=3), "MACDs": mpf.make_addplot(df['MACDs_6_12_9'].tail(tail_num), color='b', secondary_y=True, panel=3) } print('making axes0 legend') fig, axes = mpf.plot(df.tail(tail_num), type='candle', volume=True, addplot=list(ap3.values()), style='charles', returnfig=True, title=('Last '+str(tail_num)+' candles'+fname), scale_width_adjustment=dict(lines=0.25)) axes[0].legend([None](len(ap3)+2)) handles = axes[0].get_legend().legendHandles axes[0].legend(handles=handles[2:], labels=list(ap3.keys()), loc='upper left', fontsize='x-small') #axes[0].legend(loc='upper left', fontsize='x-small') # IPydisplay.Image(ourpath) print(axes) axes[4].set_ylabel("MACD") axes[6].set_ylabel("StochRSI") print(axes) print(len(ap3)) try: axes[4].legend([None](len(ap3)+2)) axes[4].legend(handles=handles[2:], labels=['MACDh', 'MACDs'], loc='center left', fontsize='x-small') except Exception as e: print('error making legend axis4') print(e) print('making axes6 legend') try: # axes[6].legend([None](len(ap3)+2)) # axes[6].legend([None]*(2+2)) #handles6 = axes[6].get_legend().legendHandles axes[6].legend(handles=handles[2:], labels=['stochrsi_K', 'stochrsi_D'], loc='center left', fontsize='x-small') except Exception as e: print('error making legend axis6') print(e) fig.savefig('plots/'+fname, dpi=300) https://user-images.githubusercontent.com/97939226/175432610-9a387d8d-42ea-465c-83b5-b688073dffa7.png you see ax6 , the stochrsi subplot on the bottom....i dont understand how to reference that handles of legend should be the correct colors. its obviuosly giving the colors of the top panels first 2...but no matter what i tried n read in the docs, i couldnt find examples both ref'd panels legend and from a addplot list. thanks wow! How do you get the candles etc so crips in your image from the mplfinance save file? would love mine to look like this. As an example, here's what my candles look like. not bad but it's not the view that i want and struggling to make it look crisper and larger in context of the overall saved image. also want to add the legend. https://ibb.co/g6cVcy8 https://ibb.co/g6cVcy8 Is there any updates on the LEGENDS capability within the package yet? — Reply to this email directly, view it on GitHub <#181 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD4NKOSLOV2EY6YFEQRXGELXNC4AXANCNFSM4OCESKDQ. You are receiving this because you commented.

i think youre responding to the code i copied from someone else

TraderMan999 avatar Jun 26 '23 20:06 TraderMan999

https://ibb.co/g6cVcy8

Can anyone suggest what i can do different to make these candles appear relatively bigger on this image? ive spent hours changing the various figsize parameters, dpi, figscale, etc to no avail. Here's some sample code.

mpf.plot(data,figscale=1.25,style='yahoo',type='candle',
               update_width_config=dict(candle_linewidth=0.4),
               title=newtitle,savefig=dict(fname='./flashcards/' + savedPlotFileName,dpi=400,bbox_inches='tight'),
                #hlines=dict(hlines=[midnightOpen,londonhigh,londonlow,
                #                                fib_62, fib_705, fib_79,fib_21, fib_295, fib_38],
                #                                colors=['b','g','r','r','g','k','r','g','k']),
                hlines=dict(hlines=[midnightOpen, londonhigh, londonlow],
                                               colors=['b', 'g', 'r', 'r', 'g', 'k'],
                                               linewidths=(1, 1, 1, 1, 1, 1),
                                               linestyle=['dotted', 'dotted', 'dotted']),
                fill_between=dict(y1=minlow,y2=minhigh,where=where_values, alpha=0.5, color='g'))

image

TraderMan999 avatar Jun 26 '23 20:06 TraderMan999

There are a few things you can try, lsited here in the order of what I suspect is most likely to help:

  1. For sure getting rid of the lower hlines and possibly setting ylim=(4075,4175) will help. By the way, the code you posted doesn't seem to match the plot image that you posted.
  2. resample to plot fewer candles. click here for more information
  3. scale_width_adjustment=dict(candle=1.35) (play with various values to see what works best)
  4. Play around with various figscale= values. Sometimes making this larger, or even smaller, can improve candle appearance.
  5. Similarly playing with different values of dpi may (or may not) help.

DanielGoldfarb avatar Jun 26 '23 22:06 DanielGoldfarb

There are a few things you can try, lsited here in the order of what I suspect is most likely to help:

  1. For sure getting rid of the lower hlines and possibly setting ylim=(4075,4175) will help. By the way, the code you posted doesn't seem to match the plot image that you posted.
  2. resample to plot fewer candles. click here for more information
  3. scale_width_adjustment=dict(candle=1.35) (play with various values to see what works best)
  4. Play around with various figscale= values. Sometimes making this larger, or even smaller, can improve candle appearance.
  5. Similarly playing with different values of dpi may (or may not) help.

thanks let me give that a try.

weird i think youre right. i must have made a copy / paste error. let me post below for clarification oops i see what i did. i grabbed the wrong image url for the post. ive posted the correct one here below

https://ibb.co/NK0GYCq

The lower hlines are fibs im tracking but ive pondered the value of having them there when the actual candles are so far from them so that could also be a compromise with a little if then else logic i can add

AND AS ALWAYS THANK YOU FOR THE QUICK RESPONSE. I LOVE HOW ENGAGED YOU ARE IN YOUR PRODUCT FOR YOUR USER COMMUNITY. ONE OF THE BEST!

TraderMan999 avatar Jun 27 '23 00:06 TraderMan999

The ylim definitely helped. i can probably live with that. thanks for that suggestion

TraderMan999 avatar Jun 27 '23 01:06 TraderMan999