Vertically offset tick labels in Matplotlib - python

I want tick labels to be placed above the tick instead of centered on the tick.
This is how it looks now:
This is how I want it to look:
I've read about tick label formatting here but I could only figure out how modify horizontal padding. I think I need to modify vertical padding. Does anyone have an idea how I could do this?

You can set the vertical alignment of the tick labels directly to shift them up.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randn(100,)
fig, ax = plt.subplots(2, 1)
ax[0].plot(data)
ax[0].set_title("No shift")
ax[1].plot(data)
for tick in ax[1].get_yticklabels():
tick.set_verticalalignment("bottom")
ax[1].set_title("With shift")
fig.tight_layout()
plt.show()
You can see that in the first subplot the labels are centered on the ticks, while on the bottom plot they are above it.

Related

customize ticks label when sharex is on in matplotlib

I have two stacked subplots which share the x axis, for both subplots visibility of ticks is set to false because I don't want to see tick labels. after having plotted both subplots, I would like to put some extra ticks on x-asis, only for second subplot, but they don't have to became the main ticks.
I mean, doing this:
#xticks = list of x points
#xlabs = list of labels
#secondplot.set_xticks(xticks)
#secondplot.set_xticklabels(xlabs)
will change the first sublplot grid according to these new ticks as if they became the new major ticks. is there a way to label just some x-axis point in second subplot without affecting the whole plots area? thank you
I know im late to the party but I faced a similar problem and want to share my solution, in case anyone else needs help.
You can use matplotlib.axes.Axes.tick_params to control the style of both major and minor ticks of the axes. Setting the tick lengths of the first subplot to 0 should do the trick:
ax.tick_params(axis="x", which="both", length=0.)
axis ("x", "y" or "both") selects the axes, on which the setting has an effect, which ("major", "minor" or "both") chooses the tick type.
Of course you can then also set major and minor ticks with ax.set_xticks(ticks, minor=False). A full example:
import matplotlib.pyplot as plt
fig, axarr = plt.subplots(2, 1, sharex="col")
axarr[0].plot(range(11))
axarr[1].plot(range(11)[::-1])
axarr[0].tick_params(axis="x", which="both", length=0.)
axarr[1].set_xticks(range(0, 11, 3))
axarr[1].set_xticks(range(0, 11), minor=True)
plt.show()
which yields: https://i.stack.imgur.com/oc7y0.png
This works for removing the tick labels from a single axis when using sharex, but I don't see a solution to also remove the ticks..
import matplotlib.pylab as pl
pl.figure()
ax1=pl.subplot(211)
ax1.plot([0,10],[0,10])
ax2=pl.subplot(212, sharex=ax1)
ax2.plot([0,10],[10,0])
pl.setp(ax1.get_xticklabels(), visible=False)

Gridlines that overlap with axes spines have different width from other gridlines

I'm using Seaborn to make some plots using the whitegrid style. After calling despine(), I'm seeing that the gridlines that would overlap with the axes spines have smaller linewidth than the other gridlines. But it seems like this only happens when I save the plots as pdf. I'm sharing
three different figures with different despine configurations that show the effect.
Does anyone know why this occurs? And is there a simple fix?
PDF plot with all spines
PDF plot that despines all axes
PDF plot that despines left, top, and right axes
Code:
splot = sns.boxplot(data=df, palette=color, whis=np.inf, width=0.5, linewidth = 0.5)
splot.set_ylabel('Normalized WS')
plt.xticks(rotation=90)
plt.tight_layout()
sns.despine(left=True, bottom=True)
plt.savefig('test.pdf', bbox_inches='tight')
Essentially what's happening here is that the grid lines are centered on the tick position, so the outer half of the extreme grid lines are not drawn because they extend past the limits of the axes.
One approach is to disable clipping for the grid lines:
import numpy as np
import seaborn as sns
sns.set(style="whitegrid", rc={"grid.linewidth": 5})
x = np.random.randn(100, 6)
ax = sns.boxplot(data=x)
ax.yaxis.grid(True, clip_on=False)
sns.despine(left=True)
My hacking solution now is to not despine the top and bottom axes and make them the same width as the gridlines. This is not ideal. If someone can point out a way to fix the root cause, I will really appreciate that.

Matplotlib: How do I have the xtick labels apear on the other side of the x-axis?

In this bar chart:
How do I make the x-axis labels appear in the bars of the bar-chart and left-aligned with the x-axis?
I tried the ax.xaxis.labelpad() method but it does not seem to do anything.
you can set the y location of the ticks when you call set_xticklabels. So, if you set y to something small but positive, it should be placed inside the bars.
For example:
import matplotlib.pyplot as plt
fig,ax = plt.subplots(1)
ax.bar([0,1,2,3],[7900,9400,8700,9990],facecolor='#5080B0',edgecolor='k',width=0.3)
ax.set_xticks([0.15,1.15,2.15,3.15])
ax.set_xticklabels(['beek1','beek2','orbath','Kroo'],
rotation='vertical',y=0.05,va='bottom')
Produces the following plot:

autofmt_xdate deletes x-axis labels of all subplots

I use autofmt_xdate to plot long x-axis labels in a readable way. The problem is, when I want to combine different subplots, the x-axis labeling of the other subplots disappears, which I do not appreciate for the leftmost subplot in the figure below (two rows high). Is there a way to prevent autofmt_xdate from quenching the other x-axis labels? Or is there another way to rotate the labels? As you can see I experimented with xticks and "rotate" as well, but the results were not satisfying because the labels were rotated around their center, which resulted in messy labeling.
Script that produces plot below:
from matplotlib import pyplot as plt
from numpy import arange
import numpy
from matplotlib import rc
rc("figure",figsize=(15,10))
#rc('figure.subplot',bottom=0.1,hspace=0.1)
rc("legend",fontsize=16)
fig = plt.figure()
Test_Data = numpy.random.normal(size=20)
fig = plt.figure()
Dimension = (2,3)
plt.subplot2grid(Dimension, (0,0),rowspan=2)
plt.plot(Test_Data)
plt.subplot2grid(Dimension, (0,1),colspan=2)
for i,j in zip(Test_Data,arange(len(Test_Data))):
plt.bar(i,j)
plt.legend(arange(len(Test_Data)))
plt.subplot2grid(Dimension, (1,1),colspan=2)
xticks = [r"%s (%i)" % (a,b) for a,b in zip(Test_Data,Test_Data)]
plt.xticks(arange(len(Test_Data)),xticks)
fig.autofmt_xdate()
plt.ylabel(r'$Some Latex Formula/Divided by some Latex Formula$',fontsize=14)
plt.plot(Test_Data)
#plt.setp(plt.xticks()[1],rotation=30)
plt.tight_layout()
#plt.show()
This is actually a feature of the autofmt_xdate method. From the documentation of the autofmt_xdate method:
Date ticklabels often overlap, so it is useful to rotate them and right align them. Also, a common use case is a number of subplots with shared xaxes where the x-axis is date data. The ticklabels are often long, and it helps to rotate them on the bottom subplot and turn them off on other subplots, as well as turn off xlabels.
If you want to rotate the xticklabels of the bottom right subplot only, use
plt.setp(plt.xticks()[1], rotation=30, ha='right') # ha is the same as horizontalalignment
This rotates the ticklabels 30 degrees and right aligns them (same result as when using autofmt_xdate) for the bottom right subplot, leaving the two other subplots unchanged.

How to simultaneously remove top and right axes and plot ticks facing outwards?

I would like to make a matplotlib plot having only the left and bottom axes, and also the ticks facing outwards and not inwards as the default. I found two questions that address both topics separately:
In matplotlib, how do you draw R-style axis ticks that point outward from the axes?
How can I remove the top and right axis in matplotlib?
Each of them work on its own, but unfortunately, both solutions seem to be incompatible with each other. After banging my head for some time, I found a warning in the axes_grid documentation that says
"some commands (mostly tick-related) do not work"
This is the code that I have:
from matplotlib.pyplot import *
from mpl_toolkits.axes_grid.axislines import Subplot
import matplotlib.lines as mpllines
import numpy as np
#set figure and axis
fig = figure(figsize=(6, 4))
#comment the next 2 lines to not hide top and right axis
ax = Subplot(fig, 111)
fig.add_subplot(ax)
#uncomment next 2 lines to deal with ticks
#ax = fig.add_subplot(111)
#calculate data
x = np.arange(0.8,2.501,0.001)
y = 4*((1/x)**12 - (1/x)**6)
#plot
ax.plot(x,y)
#do not display top and right axes
#comment to deal with ticks
ax.axis["right"].set_visible(False)
ax.axis["top"].set_visible(False)
#put ticks facing outwards
#does not work when Sublot is called!
for l in ax.get_xticklines():
l.set_marker(mpllines.TICKDOWN)
for l in ax.get_yticklines():
l.set_marker(mpllines.TICKLEFT)
#done
show()
Changing your code slightly, and using a trick (or a hack?) from this link, this seems to work:
import numpy as np
import matplotlib.pyplot as plt
#comment the next 2 lines to not hide top and right axis
fig = plt.figure()
ax = fig.add_subplot(111)
#uncomment next 2 lines to deal with ticks
#ax = fig.add_subplot(111)
#calculate data
x = np.arange(0.8,2.501,0.001)
y = 4*((1/x)**12 - (1/x)**6)
#plot
ax.plot(x,y)
#do not display top and right axes
#comment to deal with ticks
ax.spines["right"].set_visible(False)
ax.spines["top"].set_visible(False)
## the original answer:
## see http://old.nabble.com/Ticks-direction-td30107742.html
#for tick in ax.xaxis.majorTicks:
# tick._apply_params(tickdir="out")
# the OP way (better):
ax.tick_params(axis='both', direction='out')
ax.get_xaxis().tick_bottom() # remove unneeded ticks
ax.get_yaxis().tick_left()
plt.show()
If you want outward ticks on all your plots, it might be easier to set the tick direction in the rc file -- on that page search for xtick.direction

Categories