Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to format x,y coords in plotnine

I have very simple plotnine example:

from plotnine import ggplot, aes, geom_line
import pandas as pd

df = pd.DataFrame([[1,1], [2,4], [3,9], [4,16], [5,25]], columns=['x', 'y'])
print(df)

g = (
    ggplot(df)
    + aes(x="x", y="y")
    + geom_line()
)

g.show()

Everything is ok, except (x,y) coordinates displayed in bottom right corner (marked red): enter image description here

Is there some way to change formatting, so that I can limit number of decimal digits (something like f"{x:.4f}")?

python 3.10.12
plotnine 0.14.6

Edit: Ubuntu 22.04. matplotlib.get_backend() gives gtk4agg

like image 418
rth Avatar asked Oct 24 '25 03:10

rth


1 Answers

Under the hood, Plotnine uses Matplotlib, which enables us to combine this answer to get the relevant underlying Matplotlib objects and this answer to adjust the formatting:

import time
from plotnine import ggplot, aes, geom_line
import pandas as pd

df = pd.DataFrame([[1,1], [2,4], [3,9], [4,16], [5,25]], columns=['x', 'y'])

g = ggplot(df) + aes(x="x", y="y") + geom_line()

fig = g.draw()  # Get underlying matplotlib figure
ax = fig.get_axes()[0]
ax.fmt_xdata = lambda val: f"{val:.2f}"  # Only show two digits on x
ax.fmt_ydata = lambda val: f"{val:.2f}"  # Only show two digits on y

# Provide explicit event loop and closing behavior:
close_pressed = False
def on_close(unused_event):
    global close_pressed
    close_pressed = True
fig.canvas.mpl_connect("close_event", on_close)
fig.show()
while not close_pressed:
    fig.canvas.flush_events()
    time.sleep(0.01)

On my system, this produces:

plot after formatting coordinates

A technical caveat: since fig.show(), in contrast to matplotlib.pyplot.show(), does not provide its own event loop, I added my own (while not close_pressed: …), following Matplotlib's documentation on interactive figures. This loop might or might not be necessary, depending on your Python runtime: The event loop is not necessary for me when running the code in the Spyder IDE; in fact, it even hurts running the code there, in that with an active console, I can launch the code successfully only once. On the other hand, the loop is necessary for me when directly running it from a Python terminal. I also tried to avoid it, using import matplotlib.pyplot as plt … plt.show() instead, but I could not figure out how to produce the Plotnine figure with it.

like image 89
simon Avatar answered Oct 26 '25 06:10

simon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!