4

I am trying to plot a logarithmic plot using seaborn factorplot on a dataframe as follows

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

l1 = [0.476, 0.4427, 0.378, 0.2448, 0.13, 0.004, 0.012, 0.0933, 3.704e-05, 
    1.4762e-06, 4.046e-08, 2.99e-10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

df = pd.DataFrame(l1, columns=["y"])
df.reset_index(inplace=True)

g = sns.factorplot(x='index',y='y', data=df, aspect=2, size=8)
g.fig.get_axes()[0].set_yscale('log')
plt.grid(True,which="both",ls="--",c='gray')  

plt.show()

I get the following figure. enter image description here

Even though I changed the Y-axis scale to log and used both the gridlines, the final figure doesnt have the log scale ticks. However, the same code when used with another set of values gives me the following figure. In this case, the minimum value is limited to 10^-7

l2 = [0.29, 0.111, 0.0285, 0.0091, 0.00045, 5.49759e-05, 1.88819e-06, 0.0, 0.0, 0.0]
df = pd.DataFrame(l2, columns=["y"])
# same code as above

enter image description here

Any idea where I am being wrong?


Update 1

I follwed Diziet's answer and forced the major and minor ticks as follows

g.ax.yaxis.set_minor_locator(tkr.LogLocator(base=10, subs='all'))
g.ax.yaxis.set_minor_formatter(tkr.NullFormatter())
g.ax.set_yscale('log')


g.ax.grid(True,which="both",ls="--",c='gray')  

But it still doesnt solve the problem

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
Raja Sattiraju
  • 1,262
  • 1
  • 20
  • 42
  • 1
    Seems to be the same as [this question](https://stackoverflow.com/questions/44078409/matplotlib-semi-log-plot-minor-tick-marks-are-gone-when-range-is-large). – ImportanceOfBeingErnest Feb 26 '18 at 17:05

2 Answers2

5

The problem is that in order to set the locations of ticks for cases where the automatically chosen major ticks are more than a decade away from each other seems to require to set the subs parameter of the locator as well as the numticks manually. Here, mticker.LogLocator(base=10, subs=np.arange(0.1,1,0.1),numticks=10).

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import seaborn as sns

l1 = [0.476, 0.4427, 0.378, 0.2448, 0.13, 0.004, 0.012, 0.0933, 3.704e-05, 
    1.4762e-06, 4.046e-08, 2.99e-10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] 
df = pd.DataFrame(l1, columns=["y"])
df.reset_index(inplace=True)

g = sns.factorplot(x='index',y='y', data=df, aspect=2, size=8)
g.ax.set_yscale('log')

plt.grid(True,which="both",ls="--",c='gray')  

locmin = mticker.LogLocator(base=10, subs=np.arange(0.1,1,0.1),numticks=10)  
g.ax.yaxis.set_minor_locator(locmin)
g.ax.yaxis.set_minor_formatter(mticker.NullFormatter())

plt.show()

enter image description here

More generally also look at this question.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • By changing the number of ticks to 12 instead of 10, I got the figure the way I wanted. `locmaj = tkr.LogLocator(base=10.0,numticks=12) g.ax.yaxis.set_major_locator(locmaj) locmin = tkr.LogLocator(base=10.0, subs=np.arange(0.1,1,0.1),numticks=12) g.ax.yaxis.set_minor_locator(locmin) g.ax.yaxis.set_minor_formatter(tkr.NullFormatter())` Thanks a lot – Raja Sattiraju Feb 26 '18 at 20:31
  • I'm using matplotlib 2.2 while the answer to the other question uses earlier versions and needs to put `numticks=12` as well. Possibly that changed in between versions. – ImportanceOfBeingErnest Feb 26 '18 at 20:33
1

I do not think you are doing anything wrong. It seems to me that, in your first example, matplotlib decided (for a reason unknown to me) not to show any minor ticks, while it does for the second example.

One way to solve your issue is to force the display of minor ticks:

g = sns.factorplot(...)

ax = g.axes.flatten()[0]
ax.set_yscale('log')
ax.yaxis.set_minor_locator(matplotlib.ticker.LogLocator(base=10.0, subs='all'))
ax.yaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())

plt.grid(True,which="both",ls="--",c='gray')  
Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
  • hmmm. Sorry, I'm pretty sure the solution is with forcing the display of minor ticks, but I can't reproduce your problem, so I can't figure out how to fix it beside the general pointer above – Diziet Asahi Feb 26 '18 at 15:31
  • I have edited the question to include a minimal dataset for reproducibility – Raja Sattiraju Feb 26 '18 at 15:52