Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is ticklabel_format broken?

I am trying to plot a simple time series with years as units in the x-axis. Unfortunately pyplot seems to think these numbers should be shown in scientific format. I have seen suggestions on Stack Overflow to change this behaviour with something like this:

plt.gca().ticklabel_format(style='plain', axis='x')

or even just

plt.ticklabel_format(style='plain', axis='x')

should be the way to go. To my surprise I noticed this does absolutely nothing on my system. It has no effect, but does not trigger any errors either. What's the deal here? I know that I can set the label strings instead but clearly this is not how it's supposed to work. Since I couldn't find any mention of this bug I wanted to check if this is a common problem.

I'm running python 2.7 on Linux.

Edit:

This is basically the code I'm using. Except the values are actually read out of a textfile.

labels = ['1989', '1990', '1991', '1992', '1993', '1994', '1995', '1996', '1997', '1998']
years = [1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998]
values = [1.4, 2.3, 4.2, 3.2, 1.2, 3.6, 9.8, 10.2, 6.1, 3.2]

plt.plot(years, values, label='Random Data')
plt.autoscale(tight=True)
plt.title('Plot of some random data')
plt.legend(loc=0)
plt.ylabel('[some unit]')
plt.xlabel('year')

plt.ticklabel_format(style='plain', axis='x') # this should work but doesn't

plt.xticks(range(1989, 1989 + len(years)), labels) # this works but is cumbersome

plt.show()
plt.savefig('beispiel.jpg')
like image 881
user2504884 Avatar asked Aug 13 '13 12:08

user2504884


People also ask

How do I avoid scientific notation in Matplotlib?

If you want to disable both the offset and scientific notaion, you'd use ax. ticklabel_format(useOffset=False, style='plain') .

How do I use scientific notation in Matplotlib?

(m, n), pair of integers; if style is 'sci', scientific notation will be used for numbers outside the range 10m to 10n. Use (0,0) to include all numbers. Use (m,m) where m <> 0 to fix the order of magnitude to 10m.

How do I change the date format in Matplotlib?

Create a figure and a set of subplots using subplots() method. Plot the dataframe using plot method, with df's (Step 1) time and speed. To edit the date formatting from %d-%m-%d to %d:%m%d, we can use set_major_formatter() method.


1 Answers

Explanation of scientific notation vs. offset

What you get (+1.989e3) is not scientific notation, it is an offset.

  • Scientific notation: In matplotlib scientific notation is seen as a common factor of all the tickvalues printed at the edge of the axis. If you plot very big values on the x-axis, you might see 1e9 or something similar printed. In order to get the "correct" value at the tickmarks you have to multiply by this factor. E.g. say you get 2.2 as one of the tickvalues on the axis, with 1e9 printed at the edge of the axis. In order to get the "correct" value of this tickmark, you must multiply the tickvalue by the common factor: 2.2 * 1e9 = 2.2e9.

  • Offset: An offset is a value you have to add/subtract from the displayed tickvalues (hence the + or - next to the number). As with the scientific notation, this number is also printed at the edge of the axis. In order to get the "correct" value at the tickmarks in this case, you have to add/subtract this number (as indicated by the sign). E.g. say you get 3 as one of the tickvalues on the axis, with +1.989e3 printed at the edge of the axis. In order to get the "correct" value of this tickmark, you must add the offset to the tickvalue: 3 + 1.989e3 = 1992

So in short: scientific notation is seen as a factor by which you have to multiply the tickvalues, while an offset is a value you have to add/subtract to/from the tickvalues in order to get the "correct" value.

Solving your problem

To remove the offset printed next to your axis, you can simply disable the usage of offset values by passing useOffset=False to the ticklabel_format() call:

import matplotlib.pyplot as plt

years  = [1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998]
values = [1.4, 2.3, 4.2, 3.2, 1.2, 3.6, 9.8, 10.2, 6.1, 3.2]

plt.plot(years, values, label='Random Data')
plt.autoscale(tight=True)
plt.title('Plot of some random data')
plt.legend(loc=0)
plt.ylabel('[some unit]')
plt.xlabel('year')

plt.ticklabel_format(useOffset=False)

plt.show()
plt.savefig('beispiel.jpg')

enter image description here

like image 165
sodd Avatar answered Oct 28 '22 10:10

sodd