I am currently generating different figures with a scientific notation for the y-axis leading to ticks like 2 or 6 on some plots, but 2.5 or 8.9 on some others. I would like to always have ticks with one decimal on the y-axis, even if it adds a zero. Here is an example
import matplotlib.pyplot as plt
import numpy as np
plt.plot(np.arange(1, 10), np.arange(1, 10)**5)
ax = plt.gca()
plt.ticklabel_format(axis='y', style='sci')
ax.yaxis.major.formatter.set_powerlimits((0,0))
plt.show()
What could I add to force to plot ticks 1.0, 2.0, etc. on the y-axis ?
The ScalarFormatter
does not currently support custom formats for the ticks, such as setting numbers of decimals. However you can extend the class, so to force it to use a format that you specify. Here is an example:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import ScalarFormatter
class ScalarFormatterForceFormat(ScalarFormatter):
def _set_format(self): # Override function that finds format to use.
self.format = "%1.1f" # Give format here
plt.plot(np.arange(1, 10), np.arange(1, 10)**5)
ax = plt.gca()
yfmt = ScalarFormatterForceFormat()
yfmt.set_powerlimits((0,0))
gca().yaxis.set_major_formatter(yfmt)
plt.show()
Here is how it will look.
Since I did not manage to make the other answers work, probably because I am using subplots and axis, I create a function that simply goes around the problem of using the command plt.ticklabel_format(axis='y', style='sci')
.
The function takes the thicklabels of the y axis and converts the values to scientific notation. It calculates the value and the sign of the exponent and then modifies the plot accordingly, using ax.annotate
to place the exponent a the top left corner. The function takes as the arguments the ax that needs to be modified, so the figure needs to be declared with an axis ( ax
), and the number decimal digits to be displayed. The only unknown is the textsize
of the annotate
, which may be automatized as well. I added a couple of different plots to show the case with negative numbers or decimals.
import matplotlib.pyplot as plt
import numpy as np
def scientific_notation_y(ax, decimals=1):
v = np.asarray(ax.get_yticks().tolist())
v_abs = np.abs(v)
v_max = np.max(v_abs)
exp = 0
if v_max >= 10:
sign = '+'
while v_max >= 10:
exp = exp + 1
v_max = v_max / 10
v = v / 10**exp
elif v_max <= 1:
sign = '-'
while v_max <= 1:
exp = exp + 1
v_max = v_max * 10
v = v * 10**exp
v = np.around(v, decimals)
ax.annotate(r'1e' + sign + str(exp), xycoords='axes fraction',
xy=(0, 0), xytext=(0, 1.01), size=14)
ax.set_yticklabels(v)
return
fig, ax = plt.subplots()
ax.plot(np.arange(0, 10), np.arange(0, 10)**5)
scientific_notation_y(ax, 1)
plt.show()
fig, ax = plt.subplots()
ax.plot(np.arange(0, 10), -np.arange(0, 10)**5)
scientific_notation_y(ax, 1)
plt.show()
fig, ax = plt.subplots()
ax.plot(np.arange(0, 10), -np.arange(0, 10)/100)
scientific_notation_y(ax, 1)
plt.show()
You can get the ticks and format it like you want.
plt.plot(np.arange(1, 10), np.arange(1, 10)**5)
ax = plt.gca()
plt.ticklabel_format(axis='y', style='sci')
ax.yaxis.major.formatter.set_powerlimits((0,0))
xx, locs = plt.xticks()
ll = ['%.1f' % a for a in xx]
plt.xticks(xx, ll)
plt.show()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.