LeStivi
LeStivi

Reputation: 31

Different format of ticks on the same axis

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

Answers (2)

wwii
wwii

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()

YAxis format

Upvotes: 1

jjsantoso
jjsantoso

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])

enter image description here

Upvotes: 1

Related Questions