Reputation: 31
I am wondering if there is a way to have different format for the ticks labels on an axis.In My code below I tried two options, the first one worked but the y labels were too large for my figure size(which I cannot change), the second option I tried to change the ticks labels format one at the time, but it resulted on nothing being displayed, so my question is to know if there is a work-around. Thanks
PS:first time using matplotlib to graph
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoMinorLocator
from matplotlib.ticker import LogLocator
import matplotlib.ticker as mtick
fig, ax = plt.subplots()
#Define only minor ticks
minorLocator = LogLocator(base=10,subs='auto')
#Set the scale as a logarithmic one
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_ylim(0.00001,1000)
#Set the minor ticks
ax.xaxis.set_minor_locator(minorLocator)
ax.yaxis.set_minor_locator(minorLocator)
vals = ax.get_xticks()
ax.set_xticklabels(['{:3.2f}'.format(x) for x in vals])
'''This line below if uncommented works, but the format is not
correct and only 7 characters are displayedMy y values will be
1000.00000, 100.00000,10.0000, 1.00000, 0.10000,
etc.. '''
#ax.yaxis.set_major_formatter(mtick.PercentFormatter(decimals=5))
''' With the lines of code below which does not work, I am trying to have
the axis as 1000.00, 100.00, 10.00, 1.00, 0.1, 0.01, 0.001, 0.0001, etc..
Nothing however is displayed'''
vals = ax.get_yticks()
for x in vals:
if x > 0.001:
ax.set_yticklabels(['{:7.2f}%'.format(x*1)])
else:
ax.set_yticklabels(['{:7.5f}%'.format(x*1)])
Upvotes: 0
Views: 531
Reputation: 23783
Create a function that will return a string in the correct format then use matplotlib.ticker.FuncFormatter to designate your function as the y axis formatter. Assuming you want the y-axis labels to look like this: 1000.00, 100.00, 10.00, 1.00, 0.1, 0.01, 0.001, 0.0001
and adapting from a matplotlib example:
import math
from matplotlib.ticker import FuncFormatter
y_s = [1000, 100, 10, 1, 0.1000, 0.01000, 0.001000, 0.0001000]
x_s = [pow(10,y) for y in range(8)]
def my_format(y, pos):
# y <= 0 formats not needed for log scale axis
# use the log of the label to determine width and precision
decades = int(math.log10(y))
if decades >= 0:
decimal_places = 2
width = 1 + decades + decimal_places
else:
decimal_places = abs(decades)
width = 1 + decimal_places
# construct a format spec
fmt = '{{:{}.{}f}}%'.format(width,decimal_places)
return fmt.format(y)
fig, ax = plt.subplots()
ax.set_xscale('log')
ax.set_yscale('log')
##ax.set_ylim(min(y_s)/10,max(y_s)*10)
ax.set_ylim(0.00001,1000)
ax.yaxis.set_major_formatter(formatter)
plt.plot(x_s,y_s)
plt.show()
plt.close()
Upvotes: 1
Reputation: 1758
In your second option you need to pass a list to the set_yticklabels
with all the labels in the format you want, not one by one. A list comprehension should work:
vals = ax.get_yticks()
ax.set_yticklabels(['{:7.2f}%'.format(x*1) if x > 0.001 else '{:7.5f}%'.format(x*1) for x in vals])
Upvotes: 1