I'm trying to visualize a simple order book dataframe with a seaborn catplot. However, when I set the format of the x tick labels of the ax of the catplot, it changes the values of the labels to being the index (0-10 instead of 9.95-10.05). I've tried using a .barplot() directly and the same result happens. Is this something in how seaborn creates bar charts? I have never had this issue with line charts.
book = pd.DataFrame({'price': np.arange(10.05, 9.95, -0.01), 'type': '?', 'qty': 0})
book.iloc[1, 2] = 1800
book.iloc[2, 2] = 500
book.iloc[3, 2] = 500
book.iloc[4, 2] = 100
book.iloc[0:6, 1] = 'Ask'
book.iloc[6, 2] = 100
book.iloc[7, 2] = 200
book.iloc[8, 2] = 600
book.iloc[9, 2] = 2500
book.iloc[6:11, 1] = 'Bid'
cat = sns.catplot(x='price', y='qty', data=book, hue='type', kind='bar')
cat.tick_params(axis='x', rotation=45)
cat.ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: f'{x:.2f}'))
You need to convert from the integer x-axis indices back to the corresponding price
values in the dataframe.
For example, like so:
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
import pandas as pd
import seaborn as sns
book = pd.DataFrame(
{"price": np.arange(9.95, 10.05, 0.01), "type": "?", "qty": 0}
)
book.iloc[1, 2] = 1800
book.iloc[2, 2] = 500
book.iloc[3, 2] = 500
book.iloc[4, 2] = 100
book.iloc[0:6, 1] = "Ask"
book.iloc[6, 2] = 100
book.iloc[7, 2] = 200
book.iloc[8, 2] = 600
book.iloc[9, 2] = 2500
book.iloc[6:11, 1] = "Bid"
fig, ax = plt.subplots(figsize=(6, 4), dpi=150)
sns.barplot(
x="price",
y="qty",
data=book,
hue="type",
ax=ax,
order=book["price"][::-1],
dodge=False,
)
ax.set_xticks(range(len(book["price"])))
ax.set_xticklabels(book["price"].round(2), rotation=45)
ax.xaxis.set_major_formatter(
ticker.FuncFormatter(lambda x, pos: f'${book["price"].iloc[x]:.2f}')
)
plt.tight_layout()
plt.show()
Note: I'm not 100% sure if there is an error in the sample code you provide or not, but, oddly, it was necessary to change the prices range (defined with
np.arange
) and yet then reverse the order of the plotted data to obtain a plot that matched the expected output provided and shown in question.