Inconsistent font size for scientific notation in axis - python

I'm trying to make a plot for which the x axis will show in scientific notation. The way I found how to do so is to use the ticklabel_format function. Unfortunately this does not respect the font size I assign to the numbers shown in the axis, see image below:
The 1e-12 and 1e4 are displayed in a different font size even though I set equal label sizes.
How could I fix this? (A MWE is below)
import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0.0, 10000.0, 10.)
s = np.sin(np.pi*t)*np.exp(-t*0.0001)
fig, ax = plt.subplots()
ax.tick_params(axis='both', which='major', labelsize=7)
plt.ticklabel_format(style='sci', axis='x', scilimits=(0,0), labelsize=7)
plt.plot(t,s)
plt.show()

According to ticklabel_format documentation, the function does not accept labelsize parameter.
You can change the font size using matplotlib.rc:
plt.rc('font', size=7)

I think this will help you, without change the global setting:
ax.yaxis.get_offset_text().set_fontsize(size)

I guess it's because that scientific representation is not treated as tick label, you can use:
import matplotlib
matplotlib.rc('font', size=7)
or
matplotlib.rcParams['font.size']=7
and remove labelsize=7 in ax.tick_params

Related

How to fix the y axis auto-scaling offset error in Matplotlib chart [duplicate]

I've been trying to suppress scientific notation in pyplot for a few hours now. After trying multiple solutions without success, I would like some help.
plt.plot(range(2003,2012,1),range(200300,201200,100))
# several solutions from other questions have not worked, including
# plt.ticklabel_format(style='sci', axis='x', scilimits=(-1000000,1000000))
# ax.get_xaxis().get_major_formatter().set_useOffset(False)
plt.show()
Is ticklabel_format broken? does not resolve the issue of actually removing the offset.
plt.plot(np.arange(1e6, 3 * 1e7, 1e6))
plt.ticklabel_format(useOffset=False)
In your case, you're actually wanting to disable the offset. Using scientific notation is a separate setting from showing things in terms of an offset value.
However, ax.ticklabel_format(useOffset=False) should have worked (though you've listed it as one of the things that didn't).
For example:
fig, ax = plt.subplots()
ax.plot(range(2003,2012,1),range(200300,201200,100))
ax.ticklabel_format(useOffset=False)
plt.show()
If you want to disable both the offset and scientific notaion, you'd use ax.ticklabel_format(useOffset=False, style='plain').
Difference between "offset" and "scientific notation"
In matplotlib axis formatting, "scientific notation" refers to a multiplier for the numbers show, while the "offset" is a separate term that is added.
Consider this example:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(1000, 1001, 100)
y = np.linspace(1e-9, 1e9, 100)
fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()
The x-axis will have an offset (note the + sign) and the y-axis will use scientific notation (as a multiplier -- No plus sign).
We can disable either one separately. The most convenient way is the ax.ticklabel_format method (or plt.ticklabel_format).
For example, if we call:
ax.ticklabel_format(style='plain')
We'll disable the scientific notation on the y-axis:
And if we call
ax.ticklabel_format(useOffset=False)
We'll disable the offset on the x-axis, but leave the y-axis scientific notation untouched:
Finally, we can disable both through:
ax.ticklabel_format(useOffset=False, style='plain')

Have the same font for numbers on axis and for axis label in Matplotlib

I have the following code to create the plot depicted below:
import matplotlib.pyplot as plt
x = [...]
y = [...]
fig = plt.figure()
ax = fig.gca()
ax.set_xlabel(r'$\mathsf{Concentration [mol/m^{3}]}$')
ax.set_ylabel(r'$\mathsf{Diffusion Coefficient [m^2/s]}$')
plt.semilogy(x, y)
plt.grid(True, which="both")
plt.autoscale()
plt.savefig("coeff.pdf")
plt.show()
It's perfectly possible to use LaTeX math notation for the axis label. Unfortunately, the numbers at the ticks/grid lines have another font:
How can I make sure the axis labels and the numbers have the same font and style?
You need to set the mathtext font to the regular font:
from matplotlib import rcParams
rcParams['mathtext.default'] = 'regular'
This works for using mathtext for equation rendering. If you use Latex, you should take a look here.

How to prevent overlapping x-axis labels in sns.countplot

For the plot
sns.countplot(x="HostRamSize",data=df)
I got the following graph with x-axis label mixing together, how do I avoid this? Should I change the size of the graph to solve this problem?
Having a Series ds like this
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(136)
l = "1234567890123"
categories = [ l[i:i+5]+" - "+l[i+1:i+6] for i in range(6)]
x = np.random.choice(categories, size=1000,
p=np.diff(np.array([0,0.7,2.8,6.5,8.5,9.3,10])/10.))
ds = pd.Series({"Column" : x})
there are several options to make the axis labels more readable.
Change figure size
plt.figure(figsize=(8,4)) # this creates a figure 8 inch wide, 4 inch high
sns.countplot(x="Column", data=ds)
plt.show()
Rotate the ticklabels
ax = sns.countplot(x="Column", data=ds)
ax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha="right")
plt.tight_layout()
plt.show()
Decrease Fontsize
ax = sns.countplot(x="Column", data=ds)
ax.set_xticklabels(ax.get_xticklabels(), fontsize=7)
plt.tight_layout()
plt.show()
Of course any combination of those would work equally well.
Setting rcParams
The figure size and the xlabel fontsize can be set globally using rcParams
plt.rcParams["figure.figsize"] = (8, 4)
plt.rcParams["xtick.labelsize"] = 7
This might be useful to put on top of a juypter notebook such that those settings apply for any figure generated within. Unfortunately rotating the xticklabels is not possible using rcParams.
I guess it's worth noting that the same strategies would naturally also apply for seaborn barplot, matplotlib bar plot or pandas.bar.
You can rotate the x_labels and increase their font size using the xticks methods of pandas.pyplot.
For Example:
import matplotlib.pyplot as plt
plt.figure(figsize=(10,5))
chart = sns.countplot(x="HostRamSize",data=df)
plt.xticks(
rotation=45,
horizontalalignment='right',
fontweight='light',
fontsize='x-large'
)
For more such modifications you can refer this link:
Drawing from Data
If you just want to make sure xticks labels are not squeezed together, you can set a proper fig size and try fig.autofmt_xdate().
This function will automatically align and rotate the labels.
plt.figure(figsize=(15,10)) #adjust the size of plot
ax=sns.countplot(x=df['Location'],data=df,hue='label',palette='mako')
ax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha="right") #it will rotate text on x axis
plt.tight_layout()
plt.show()
you can try this code & change size & rotation according to your need.
I don't know whether it is an option for you but maybe turning the graphic could be a solution (instead of plotting on x=, do it on y=), such that:
sns.countplot(y="HostRamSize",data=df)

Matplotlib: disable powers of ten in log plot

Is there a simple way to make matplotlib not show the powers of ten in a log plot, and instead just show the numbers? I.e., instead of [10^1, 10^2, 10^3] display [10, 100, 1000]? I don't want to change the tickmark locations, just want to get rid of the powers of ten.
This is what I currently have:
I can change the labels themselves via xticks, however I then get mismatching fonts or sizes for the y tick labels. I am using TeX for this text. I've tried the following:
xx, locs = xticks()
ll = [r'\rm{%s}' % str(a) for a in xx]
xticks(xx, ll)
This gives the following result:
In this particular case, I could use the same LaTeX roman font, but the sizes and looks are different to those in the y axis. Plus, if I used a different LaTeX font in matplotlib this is going to be problematic.
Is there a more flexible way of switching off the power of ten notation?
Use a ScalarFormatter:
from matplotlib import rc
rc('text', usetex=True)
rc('font', size=20)
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot(111)
ax.semilogx(range(100))
ax.xaxis.set_major_formatter(ScalarFormatter())
plt.show()

Matplotlib make tick labels font size smaller

In a matplotlib figure, how can I make the font size for the tick labels using ax1.set_xticklabels() smaller?
Further, how can one rotate it from horizontal to vertical?
There is a simpler way actually. I just found:
import matplotlib.pyplot as plt
# We prepare the plot
fig, ax = plt.subplots()
# We change the fontsize of minor ticks label
ax.tick_params(axis='both', which='major', labelsize=10)
ax.tick_params(axis='both', which='minor', labelsize=8)
This only answers to the size of label part of your question though.
To specify both font size and rotation at the same time, try this:
plt.xticks(fontsize=14, rotation=90)
Please note that newer versions of MPL have a shortcut for this task. An example is shown in the other answer to this question: https://stackoverflow.com/a/11386056/42346
The code below is for illustrative purposes and may not necessarily be optimized.
import matplotlib.pyplot as plt
import numpy as np
def xticklabels_example():
fig = plt.figure()
x = np.arange(20)
y1 = np.cos(x)
y2 = (x**2)
y3 = (x**3)
yn = (y1,y2,y3)
COLORS = ('b','g','k')
for i,y in enumerate(yn):
ax = fig.add_subplot(len(yn),1,i+1)
ax.plot(x, y, ls='solid', color=COLORS[i])
if i != len(yn) - 1:
# all but last
ax.set_xticklabels( () )
else:
for tick in ax.xaxis.get_major_ticks():
tick.label.set_fontsize(14)
# specify integer or one of preset strings, e.g.
#tick.label.set_fontsize('x-small')
tick.label.set_rotation('vertical')
fig.suptitle('Matplotlib xticklabels Example')
plt.show()
if __name__ == '__main__':
xticklabels_example()
Alternatively, you can just do:
import matplotlib as mpl
label_size = 8
mpl.rcParams['xtick.labelsize'] = label_size
Another alternative
I have two plots side by side and would like to adjust tick labels separately.
The above solutions were close however they were not working out for me. I found my solution from this matplotlib page.
ax.xaxis.set_tick_params(labelsize=20)
This did the trick and was straight to the point. For my use case, it was the plot on the right that needed to be adjusted. For the plot on the left since I was creating new tick labels I was able to adjust the font in the same process as seting the labels.
ie
ax1.set_xticklabels(ax1_x, fontsize=15)
ax1.set_yticklabels(ax1_y, fontsize=15)
thus I used for the right plot,
ax2.xaxis.set_tick_params(labelsize=24)
ax2.yaxis.set_tick_params(labelsize=24)
A minor subtlety... I know... but I hope this helps someone :)
Bonus points if anyone knows how to adjust the font size of the order of magnitude label.
plt.tick_params(axis='both', which='minor', labelsize=12)
In current versions of Matplotlib, you can do axis.set_xticklabels(labels, fontsize='small').
The following worked for me:
ax2.xaxis.set_tick_params(labelsize=7)
ax2.yaxis.set_tick_params(labelsize=7)
The advantage of the above is you do not need to provide the array of labels and works with any data on the axes.
For smaller font, I use
ax1.set_xticklabels(xticklabels, fontsize=7)
and it works!
You can also change label display parameters like fontsize with a line like this:
zed = [tick.label.set_fontsize(14) for tick in ax.yaxis.get_major_ticks()]

Categories

Resources