Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong location of Y-tick-labels. #587

Open
AureliusMarcusHu opened this issue Jan 23, 2023 · 5 comments
Open

Wrong location of Y-tick-labels. #587

AureliusMarcusHu opened this issue Jan 23, 2023 · 5 comments
Labels
question Further information is requested

Comments

@AureliusMarcusHu
Copy link

AureliusMarcusHu commented Jan 23, 2023

Dear Mr. Goldfarb, once again I ask for your assistance in solving a problem. I'm still working on an all in one solution, but this time it is build around mplfinance and pandas_ta. As you can see in the screen dump, this plot is based on the default style of mplfinance. But I can change it on the fly by the button 'settings'. With settings you can choose out all the mplfinance types and styles. It is too hard to discus at once all the options i wrote so far. But it is interactive and based on tkinter and TkAgg or Agg backend.

The problem:
Adding a secondary Yaxis on the first plot of mplfinance 'the date-price plot'. The secondary Y-axis contain the fibonacci levels and the values feeded by a dict. As you can see the lines will be plot correct, no problem. The major failure is that the Y-tick-labels don't follow the Y- ticks. The tick-labels always will be plotted on de opposite site of the Y-ticks. Whatever I try. The 'twinx' is not a solution because it block the cursor acces to the first plot axes[0] the 'date-price plot', for a dark reason. I don't offer the cursor for it, because it works fast and fine. It plot the date and price value left on the bottom toolbar. The minor problem after adding the fibonacci levels, the grid of the price ticks will be lost. Below you will find the function how I plot the fibonacci lines and config of the secondary Y-axis. I will hope You will and can help me ? Many thanks in advance.

def set_fibs():
    global fib, axes
    bolds = ['0.0', '100.0', '200.0', '300.0', '400.0', '500.0', '600.0', '700.0', '800.0', '900.0']
    yliFor = []
    yliLoc = []
    limit = axes[0].get_ylim()
    y2 = axes[0].secondary_yaxis('left')
    y2.set_ylim(limit[0], limit[1])
    for k, v in fib.items():
        if v <= limit[1] and v >= limit[0]:
            tmp = k + ': ' + "{:.3f}".format(v)
            yliFor.append(tmp)
            yliLoc.append(v)
            if any(sb in k for sb in bolds):
                axes[0].axhline(v, linestyle='solid', color='brown', lw=0.9, label=k)
            else:
                if 'Fs' in k:
                    axes[0].axhline(v, linestyle='dashed', color='orange', lw=0.5, label=k)
                else:
                    axes[0].axhline(v, linestyle='dashed', color='brown', lw=0.5, label=k)
    y2.axes.set_yticks(yliLoc)
    y2.axes.yaxis.set_ticklabels(yliFor, fontsize=8, color='brown')
    for it in y2.get_yticklabels():
        txt = it.get_text()
        if 'Fs' in txt:
            it.set_color('orange')
    y2.set_ylabel('Fibonacci', color='brown')
    return

screendump

data.zip

@AureliusMarcusHu AureliusMarcusHu added the question Further information is requested label Jan 23, 2023
@AureliusMarcusHu
Copy link
Author

AureliusMarcusHu commented Jan 23, 2023

Dear Mr GoldFarb, in the mean time I have found a solution. It is not exactly what I want, but I can live with it. It is possible to plot the Fibonacci sublevels 'Fs' in a different color but, I can't get the tick-labes not in a separate color. The problem about the wrong site of the Y-axis label is solved and the orignal mplfinance grid of the price is back. The chart is beautiful thanks to 'mplfinance'. If you have a solution for the last problem, you are always welcome ...
Below a chart in mplfinance 'nightclouds' style. Are you interested in the code to set the fibonacci levels ?

image

@DanielGoldfarb
Copy link
Collaborator

@AureliusMarcusHu

This is an interesting problem that I would certainly like to delve into. There isn't much that I can do without seeing more of the code. The problem almost certainly lies in the interactions between the matplotlib methods that you are calling directly and what mplfinance is doing internally. Therefore I would have to see how you are going from (1) getting data, to (2) calling mplfinance, to (3) the various other matplotlib-related things you are doing after calling mplfinance. If you are not comfortable sharing your code publically here, feel free to post your code somewhere (for example on github you can creating a private repository and then share that repository with specific github users), or you can email the code to me at [email protected]

@AureliusMarcusHu
Copy link
Author

AureliusMarcusHu commented Jan 24, 2023

Dear Mr. Goldfarb, The final solution, all problems are solved the way I wanted. Look at the screen dump. This time mplfinance yahoo style.

image

def set_fibs(fib, axes):
    bolds = ['0.0', '100.0', '200.0', '300.0', '400.0', '500.0', '600.0', '700.0', '800.0', '900.0']
    Locl = []
    Frml = []

    limits = axes[0].get_ylim()
    for k, v in fib.items():
        if v <= limits[1] and v >= limits[0]:
            tmp = k + ': ' + "{:.3f}".format(v)
            if any(sb in k for sb in bolds):
                axes[0].axhline(v, linestyle='solid', color='sienna', lw=0.9)
                Locl.append(v)
                Frml.append(tmp)
            else:
                if 'Fs' in k:
                    axes[0].axhline(v, linestyle='dotted', color='orange', lw=0.5)
                    Locl.append(v)
                    Frml.append(tmp)
                else:
                    axes[0].axhline(v, linestyle='dashdot', color='sienna', lw=0.5)
                    Locl.append(v)
                    Frml.append(tmp)
    if len(Locl) > 0:
        y2 = axes[0].secondary_yaxis('left')
        y2.set_ylim(limits[0], limits[1])
        y2.set_yticks(Locl)
        y2.set_yticklabels(Frml, fontsize=9, color='sienna')
        for it in y2.get_yticklabels():
            txt = it.get_text()
            if 'Fs' in txt:
                it.set_color('orange')
        y2.set_ylabel('Fibonacci', color='sienna')
    return axes

Below the way I call mplfinance plot, all parameters are dynamic as you can see. After I call 'set_fibs' , very simple and straightforward. I forward the 'mplfinance axes' as parameter to the 'set_fibs' function and the parameter 'fib' is a dict. Parameter 'cdf' is a pandas dataframe containing the periods you see in the plot on the sreen. In 'set_fibs' I add the fibonacci lines to the first object axes[0] from the mplfinance axes objects and create a secondary y-axis called y2 and set the ticks, tick-labels and the y2-axis-label. By this way you see on the screen 'Fm' Fib-major-level and 'Fs' Fib-sub-level in different line styles and/or colors. That's all.

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
fig, axes = plot(cdf, type=type, style=style, volume=True, returnfig=True, figsize=wsz, datetime_format='%d %b %y', linecolor='grey',title=ftit, addplot=apdl)
axes = set_fibs(fib, axes)
#In the following lines I foward the mplfigure to the TkAgg backend and tkinter. cwin is the upper frame in tkinter.
canvas = FigureCanvasTkAgg(fig, cwin)
canvas.draw()
canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=True)

test.zip is zipped with 7zip: 'ABN.NL.eod' is a csv file for pandas dataframe. 'fib.jsn' is a json dict of fibonacci levels. In the .rtf file you find the code and the explenation.

test.zip

@DanielGoldfarb
Copy link
Collaborator

@AureliusMarcusHu
Thanks. Will take a look as I have time. Your plot looks really nice. Good job!

@AureliusMarcusHu
Copy link
Author

AureliusMarcusHu commented Feb 14, 2023

Dear Mr. Goldfarb, I'm one step further. Added studies to the project. Pandas_ta and/or custom studies as well with the delivery of buy and sell signals as you can see on the plot below. Building something as a dict wrapper who translate the dict to real functions and parameters do the job. The wrapper only import the functions called in the studies dict, nothing else. The wrapper detect the number of panels and set the panel ratios too. The dict studies from the plot below look as follow.

stds = {'volume': True,
                'base': {'act': 'queu', 'pandas_ta.rma': {'series': {'close': 'close'}, 'parm': {'lenght': 5, 'offset': -4}},
                         'pandas_ta.fwma': {'series': {'close': 'base'}, 'parm': {'length': 8, 'offset': -3}}},
                'lines': {'pandas_ta.vidya': [{'series': {'close': 'base'}, 'parm': {'length': 8, 'offset': -4}, 'stls': ['dodgerblue', 'dashed', 'fast']},
                                              {'series': {'close': 'base'}, 'parm': {'length': 9, 'offset': -2}, 'stls': ['orange', 'dashed', 'slow'], 'drop': 40, 'setas': 'base'}], 'signals': 'cross'},
                'indicators': {'calculations.fisher_mod': {'series': {'seri': 'base'}, 'parm': {'lenght': 5}, 'signals': 'cross'},
                               'pandas_ta.aroon': {'series': {'high': 'high', 'low': 'low'}, 'parm': {'lenght': 34}, 'signals': 'cross'}}}

shell example

But now it gets complicated, the code works but it looks as shit. It's too much to do alone. Do you know some people who are willing to work with me to optimize and improve the python code and complete this project. I need someone who is good with classes and someone who is good with github. Also some programmers who read this and interested in the project may responce. Thanks in advance.

Best regards,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants