Search code examples
pythonpython-3.xmatplotlibf-string

f-string in yaxis.set_major_formatter


I have the following code:

import pandas as pd
from pandas import DataFrame as df
import matplotlib
from pandas_datareader import data as web
import matplotlib.pyplot as plt
import datetime
import yfinance as yf
import matplotlib.ticker as mtick
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter,
                               AutoMinorLocator)
import currency
import warnings

warnings.filterwarnings("ignore")

start = datetime.date(2000,1,1)
end = datetime.date.today()


stock =  'goog'
fig, ax = plt.subplots(dpi=300, figsize =(8,4) )
data = web.DataReader(stock, 'yahoo', start, end)
data['Close'].plot()
ax.tick_params(axis='y', colors='midnightblue')

ax.tick_params(axis='x', colors="k")
pg = yf.Ticker(stock)
# sn = pg.info['shoName']
sn = pg.info['shortName']

b = pg.info['currency']
c = currency.symbol(f"{b}")
ax.set_ylabel(f"Price ({pg.info['currency']})")
ax.xaxis.grid(False, which='minor')
ax.yaxis.set_major_formatter('${x:1.2f}')
ax.margins(x=0)
# plt.savefig(f"{sn} {end.strftime('%d - %b%Y')}", bbox_inches='tight', dpi = 500)
print(sn)
print('datetime date =', start)
plt.show()
print()

The issue i am facing is ax.yaxis.set_major_formatter('${x:1.2f}'). I need to get a f-string to evaluate c. This would give the currency of any country instead of using $ sign. However it does not seem to evaluate f-string, could you please advise any possible alternatives?


Solution

  • The tick string formatter expects a format string with x (and optionally pos):

    The field used for the tick value must be labeled x and the field used for the tick position must be labeled pos.

    That means we need to evaluate c but not x, so:

    • Either concatenate c with the format string:

      ax.yaxis.set_major_formatter(c + '{x:1.2f}')
      
    • Or pass an evaluated f-string (add f) where x's braces are escaped (single braces for c, double braces for x):

      ax.yaxis.set_major_formatter(f'{c}{{x:1.2f}}')