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

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)

Related

How to scale graphs in seaborn scatterplot [duplicate]

How do I create a plot where the scales of x-axis and y-axis are the same?
This equal ratio should be maintained even if I change the window size. Currently, my graph scales together with the window size.
I tried:
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.axis('equal')
Use Axes.set_aspect in the following manner:
from matplotlib import pyplot as plt
plt.plot(range(5))
plt.xlim(-3, 3)
plt.ylim(-3, 3)
ax = plt.gca()
ax.set_aspect('equal', adjustable='box')
plt.draw()
plt.axis('scaled')
works well for me.
See the documentation on plt.axis(). This:
plt.axis('equal')
doesn't work because it changes the limits of the axis to make circles appear circular. What you want is:
plt.axis('square')
This creates a square plot with equal axes.
Try something like:
import pylab as p
p.plot(x,y)
p.axis('equal')
p.show()
you can stretch the plot to square using this :
fig = plt.figure(figsize=(1, 1))

matplotlib last tick label still visible [duplicate]

I have a semilogx plot and I would like to remove the xticks. I tried:
plt.gca().set_xticks([])
plt.xticks([])
ax.set_xticks([])
The grid disappears (ok), but small ticks (at the place of the main ticks) remain. How to remove them?
The plt.tick_params method is very useful for stuff like this. This code turns off major and minor ticks and removes the labels from the x-axis.
Note that there is also ax.tick_params for matplotlib.axes.Axes objects.
from matplotlib import pyplot as plt
plt.plot(range(10))
plt.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labelbottom=False) # labels along the bottom edge are off
plt.show()
plt.savefig('plot')
plt.clf()
Not exactly what the OP was asking for, but a simple way to disable all axes lines, ticks and labels is to simply call:
plt.axis('off')
Alternatively, you can pass an empty tick position and label as
# for matplotlib.pyplot
# ---------------------
plt.xticks([], [])
# for axis object
# ---------------
# from Anakhand May 5 at 13:08
# for major ticks
ax.set_xticks([])
# for minor ticks
ax.set_xticks([], minor=True)
Here is an alternative solution that I found on the matplotlib mailing list:
import matplotlib.pylab as plt
x = range(1000)
ax = plt.axes()
ax.semilogx(x, x)
ax.xaxis.set_ticks_position('none')
There is a better, and simpler, solution than the one given by John Vinyard. Use NullLocator:
import matplotlib.pyplot as plt
plt.plot(range(10))
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.show()
plt.savefig('plot')
Try this to remove the labels (but not the ticks):
import matplotlib.pyplot as plt
plt.setp( ax.get_xticklabels(), visible=False)
example
This snippet might help in removing the xticks only.
from matplotlib import pyplot as plt
plt.xticks([])
This snippet might help in removing the xticks and yticks both.
from matplotlib import pyplot as plt
plt.xticks([]),plt.yticks([])
Those of you looking for a short command to switch off all ticks and labels should be fine with
plt.tick_params(top=False, bottom=False, left=False, right=False,
labelleft=False, labelbottom=False)
which allows type bool for respective parameters since version matplotlib>=2.1.1
For custom tick settings, the docs are helpful:
https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.tick_params.html
# remove all the ticks (both axes), and tick labels on the Y axis
plt.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')
Modify the following rc parameters by adding the commands to the script:
plt.rcParams['xtick.bottom'] = False
plt.rcParams['xtick.labelbottom'] = False
A sample matplotlibrc file is depicted in this section of the matplotlib documentation, which lists many other parameters like changing figure size, color of figure, animation settings, etc.
A simple solution to this problem is to set the color of the xticks to White or to whatever the background color is. This will hide the text of the xticks but not the xticks itself.
import matplotlib.pyplot as plt
plt.plot()
plt.xticks(color='white')
plt.show()
Result

How to set the number of ticks and labels of pyplot

Is there any way that I can divide an axis to a certain number of ticks and then label them? For example, I have the following plot and I want to have 4 ticks on the x axis and be able to set the labels myself.
and here's what I want to achieve (please note that the two plots are the same):
and this is the script I am using to create the plot:
import matplotlib.pyplot as plt
plt.imshow(data, cmap=plt.cm.jet)
plt.colorbar()
plt.show()
I can divide the axis using this: plt.locator_params(axis='x', nbins=4), but I could not set the labels myself.
As #ImportanceOfBeingErnest mentioned, using imshow's extent was the answer:
plt.imshow(data, extent=[0,1.5,3,0], cmap=plt.cm.jet)

adjust matplotlib subplot spacing after tight_layout

I would like to minimize white space in my figure. I have a row of sub plots where four plots share their y-axis and the last plot has a separate axis.
There are no ylabels or ticklabels for the shared axis middle panels.
tight_layout creates a lot of white space between the the middle plots as if leaving space for tick labels and ylabels but I would rather stretch the sub plots. Is this possible?
import matplotlib.gridspec as gridspec
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
fig = plt.figure()
gs = gridspec.GridSpec(1, 5, width_ratios=[4,1,4,1,2])
ax = fig.add_subplot(gs[0])
axes = [ax] + [fig.add_subplot(gs[i], sharey=ax) for i in range(1, 4)]
axes[0].plot(np.random.randint(0,100,100))
barlist=axes[1].bar([1,2],[1,20])
axes[2].plot(np.random.randint(0,100,100))
barlist=axes[3].bar([1,2],[1,20])
axes[0].set_ylabel('data')
axes.append(fig.add_subplot(gs[4]))
axes[4].plot(np.random.randint(0,5,100))
axes[4].set_ylabel('other data')
for ax in axes[1:4]:
plt.setp(ax.get_yticklabels(), visible=False)
sns.despine();
plt.tight_layout(pad=0, w_pad=0, h_pad=0);
Setting w_pad = 0 is not changing the default settings of tight_layout. You need to set something like w_pad = -2. Which produces the following figure:
You could go further, to say -3 but then you would start to get some overlap with your last plot.
Another way could be to remove plt.tight_layout() and set the boundaries yourself using
plt.subplots_adjust(left=0.065, right=0.97, top=0.96, bottom=0.065, wspace=0.14)
Though this can be a bit of a trial and error process.
Edit
A nice looking graph can be achieved by moving the ticks and the labels of the last plot to the right hand side. This answer shows you can do this by using:
ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
So for your example:
axes[4].yaxis.tick_right()
axes[4].yaxis.set_label_position("right")
In addition, you need to remove sns.despine(). Finally, there is now no need to set w_pad = -2, just use plt.tight_layout(pad=0, w_pad=0, h_pad=0)
Using this creates the following figure:

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