4

I realize that this question has been asked before(Python Pyplot Bar Plot bars disappear when using log scale), but the answer given did not work for me. I set my pyplot.bar(x_values, y_values, etc, log = True) but got an error that says:

"TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'"

I have been searching in vain for an actual example of pyplot code that uses a bar plot with the y-axis set to log but haven't found it. What am I doing wrong?

here is the code:

import matplotlib.pyplot as pyplot
ax = fig.add_subplot(111)
fig = pyplot.figure()
x_axis = [0, 1, 2, 3, 4, 5]
y_axis = [334, 350, 385, 40000.0, 167000.0, 1590000.0]
ax.bar(x_axis, y_axis, log = 1)
pyplot.show()

I get an error even when I removre pyplot.show. Thanks in advance for the help

Community
  • 1
  • 1
physics_researcher
  • 638
  • 2
  • 9
  • 22

3 Answers3

7

Are you sure that is all your code does? Where does the code throw the error? During plotting? Because this works for me:

In [16]: import numpy as np
In [17]: x = np.arange(1,8, 1)
In [18]: y = np.exp(x)

In [20]: import matplotlib.pyplot as plt
In [21]: fig = plt.figure()
In [22]: ax = fig.add_subplot(111)
In [24]: ax.bar(x, y, log=1)
Out[24]: 
[<matplotlib.patches.Rectangle object at 0x3cb1550>,
 <matplotlib.patches.Rectangle object at 0x40598d0>,
 <matplotlib.patches.Rectangle object at 0x4059d10>,
 <matplotlib.patches.Rectangle object at 0x40681d0>,
 <matplotlib.patches.Rectangle object at 0x4068650>,
 <matplotlib.patches.Rectangle object at 0x4068ad0>,
 <matplotlib.patches.Rectangle object at 0x4068f50>]
In [25]: plt.show()

Here's the plot enter image description here

wflynny
  • 18,065
  • 5
  • 46
  • 67
4

As already suggested in the comments to Greg's answer, you're indeed seeing an issue that was fixed in matplotlib 1.3 by setting the default behavior to 'clip'. Upgrading to 1.3 fixes the issue for me.

Note that it doesn't seem to matter how you apply the log scale, whether as a keyword argument to bar or via set_yscale on the axis.

See also this answer to "Logarithmic y-axis bins in python" that suggests this workaround:

plt.yscale('log', nonposy='clip')
kynan
  • 13,235
  • 6
  • 79
  • 81
1

The error is raised due to the log = True statement in ax.bar(.... I'm unsure if this a matplotlib bug or it is being used in an unintended way. It can easily be fixed by removing the offending argument log=True.

This can be simply remedied by simply logging the y values yourself.

x_values = np.arange(1,8, 1)
y_values = np.exp(x_values)

log_y_values = np.log(y_values)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(x_values,log_y_values) #Insert log=True argument to reproduce error

Appropriate labels log(y) need to be adding to be clear it is the log values.

Greg
  • 11,654
  • 3
  • 44
  • 50
  • The problem is that the bars are not filled in when I set the y_axis to log – physics_researcher Aug 04 '13 at 15:34
  • I have addressed these points in an edit. I admit it is not as pretty as logging the x axis but it is still true that the error comes from the `log=True` argument. – Greg Aug 04 '13 at 22:13
  • I guess I could manually set the axis labels-this works as a stop gap but I am still confused as to why the log=True gives me the error. – physics_researcher Aug 04 '13 at 23:58
  • Justin this must be a bug with matplotlib, I have just retried this with matplotlib 1.3 on my work computer and `log=True` works fine. What version are you using, it is perhaps worth [installing 1.3](http://matplotlib.org/dev/faq/installing_faq.html#installation). – Greg Aug 05 '13 at 07:59