Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python matplotlib ValueError for logit scale axis label

I'm getting what looks like a label positioning error when setting a label for a logit scale axis using matplotlib, here's my example:

import matplotlib.pyplot as plt;
from matplotlib.ticker import FormatStrFormatter;

x = [1,2,3,4,5];
y = [0.1,0.2,0.3,0.4,0.5];

fig,ax = plt.subplots();

ax.set_ylim([0.005,0.99]);
ax.set_yscale('logit');
ax.yaxis.set_minor_formatter(FormatStrFormatter(""));   

ax.set_xlabel("X axis");
ax.set_ylabel("Y axis"); #set y axis label (logit scale)

ax.plot(x,y);
plt.show();
plt.close();

Here's the trace:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/backends/backend_macosx.py", line 136, in _draw
    self.figure.draw(renderer)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/artist.py", line 63, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/figure.py", line 1143, in draw
    renderer, self, dsu, self.suppressComposite)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/image.py", line 139, in _draw_list_compositing_images
    a.draw(renderer)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/artist.py", line 63, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 2409, in draw
    mimage._draw_list_compositing_images(renderer, self, dsu)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/image.py", line 139, in _draw_list_compositing_images
    a.draw(renderer)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/artist.py", line 63, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/axis.py", line 1150, in draw
    self.label.draw(renderer)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/artist.py", line 63, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/text.py", line 762, in draw
    raise ValueError("posx and posy should be finite values")
ValueError: posx and posy should be finite values

Works great when I omit

ax.set_ylabel("Y axis"); #set y axis label (logit scale)

It doesn't seem to matter of the label is set before or after the axis scale. Anyone know how to work around this?

like image 304
alkali.blue Avatar asked Apr 22 '17 00:04

alkali.blue


People also ask

What is Symlog Matplotlib?

MatPlotLib with Python Log helps to make a plot with log scaling on both the X and Y axis, whereas symlog (symmetric log) is used for axis scaling.

What is Matplotlib Figsize?

figsize is a tuple of the width and height of the figure in inches, and dpi is the dots-per-inch (pixel per inch).

What are subplots Matplotlib?

Matplotlib provides a convenient method called subplots to do this. Subplots mean a group of smaller axes (where each axis is a plot) that can exist together within a single figure. Think of a figure as a canvas that holds multiple plots.


1 Answers

There is a bug in the way the text label is set, which results in a non-numeric bounding box for logit scales, see this issue on GitHub.

The solution is to add

ax.spines['left']._adjust_location()

(where 'left' can be replaced by 'right', 'top', 'bottom' depending on the axis one is interested in) in the code.

Complete example:

import matplotlib.pyplot as plt

x = [1,2,3,4,5]
y = [0.05,0.2,0.3,0.4,0.95]

fig,ax = plt.subplots()

ax.set_yscale('logit')

ax.set_xlabel("X axis")
ax.set_ylabel("Y axis")
ax.spines['left']._adjust_location()

ax.plot(x,y)
plt.show()

enter image description here

like image 107
ImportanceOfBeingErnest Avatar answered Nov 15 '22 16:11

ImportanceOfBeingErnest