PyPlot - Additional padding for xticklabels if keywords are not enough - python

I have a plot where I set my ticks and labels manually, because pyplot did not do the job to my full satisfaction. I align the labels using the following code:
for tick in self.axes.xaxis.get_minorticklabels():
tick.set_horizontalalignment('right')
tick.set_rotation(40)
This is basically fine, but I'd like the labels to move a little bit further to the left (center is too far). I only found padding for the axis label in this post, but not for the tick labels. Is there something similar like labelpad=X to move the tick labels in horizontal direction?

You can use the Axes.set_tick_params() function to adjust the padding between the axe and the tick labels (minor, major, or both)
ax.xaxis.set_tick_params(which='minor', pad=25)

Related

Matplotlib ticks and tick labels position anchored separately from axis

Is there a way to anchor the ticks and tick labels of the x-axis so that they cross the y-axis at a different location than where the actual x-axis crosses the y-axis? This can basically be accomplished with:
ax = plt.gca()
ax.get_xaxis().set_tick_params(pad=5)
or
ax.xaxis.set_tick_params(pad=500)
For example:
Except that I am working with audio file inputs and the y-axis is variable (based on the highest/lowest amplitude of the waveform). Therefore, the maximum and minimum y-axis values change depending on the audio file. I am concerned that pad=NUM will be moving around relative to the y-axis.
Therefore, I am looking for a way to accomplish what pad does, but have the ticks and tick labels be anchored at the minimum y-axis value.
As a bonus, flipping this around so that the y-axis is anchored somewhere differently than the y-axis tick labels would surely benefit someone also.
In my particular case, I have the x-axis crossing the y-axis at y=0. The x-axis ticks and tick labels will sometimes be at -1.0, sometimes at -0.5, sometimes at -0.25, etc. I always know what the minimum value of the y-axis is, and therefore want it to be the anchor point for x-axis ticks and tick labels. (In fact, I am happy to do it with only the x-axis tick labels, if it is possible to treat ticks and tick labels separately). An example of this is shown in this image above (which I accomplished with pad=500).
I looked around other threads and in the documentation, but I'm either missing it or don't know the correct terms to find it.
UPDATE: I added gridlines and was getting very unexpected behavior (e.g. linestyle and linewidth didn't work as expected) due to the top x-axis being shifted. I realized yet a better way - keep the axes (turn off the splines) and simply plot a second line at (0, 0) to (max_time, 0).
ax.plot([0,times[-1]], [0,0], color='k') # Creates a 'false' x-axis at y=0
ax.spines['top'].set_color('none') # Position unchanged
ax.spines['bottom'].set_color('none') # Position unchanged
Figured it out! I was thinking about this the wrong way...
Problem: Moving the bottom x-axis to the center and padding the tick labels
Solution: Keep the bottom x-axis where it is (turn off the bottom spine) and move the top x-axis to the center (keep top spine, but turn off ticks and tick labels).
ax.spines['top'].set_position('center')
ax.spines['bottom'].set_color('none') # Position unchanged
ax.xaxis.set_tick_params(top='off')
plt.setp() as in https://matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html#sphx-glr-gallery-images-contours-and-fields-image-annotated-heatmap-py solved the problem for me.

label gridlines in matplotlib

I try to label my vertical gridlines in a plot. I have set my xticks and also enabled my vertical grids.
ax.set_xticks([0,10,12,17])
ax.xaxis.grid(True)
Now my question is:
Is it possible to label the gridlines? For example the gridline vertical from the x value 10 should be labeled 'number 10'. Also the labels should be rotated by 90°.
I tried it with pl.text() but that can't be the best way.
Assuming ax is matplotlib.axes.Axes .
I think what you need is - Axes.set_xticklabels() function. Documentation for that is here.
Example -
ax.set_xticklabels(labels) #labels is a list of strings,that should be the labels for your xticks.

remove tick labels in Python but keep gridlines

I have a Python script which is producing a plot consisting of 3 subplots all in 1 column.
In the middle subplot, I currently have gridlines, but I want to remove the x axis tick labels.
I have tried
ax2.axes.get_xaxis().set_ticks([])
but this seems to remove the gridlines also.
How can I remove the tick labels and keep the gridlines please?
Please try this:
plt.grid(True)
ax2.axes.get_xaxes().set_ticks([])
Or maybe this:
from matplotlib.ticker import NullFormatter
ax2.axes.get_xaxis().set_major_formatter(NullFormatter())

align grid lines on two plots

I have 2 subplots in matplotlib in Python. They are stacked on top of each other.
I want to have gridlines on each plot, which I have done successfully. But each plot has a different x axis and, therefore, the vertical grid lines of the top plot are not aligned with those of the bottom plot.
I would like the grid lines of the top plot to be in the same position on the x axis as they are on the bottom plot i.e. the vertical grid lines in both plots should be aligned.
I imaging that I can tell my grid lines exactly where to be, and so I could achieve my goal by adjusting the lines until they match as well as possible.
I just hoped that there might be some easier way that would just allow me to align the gridlines on both plots.
Edit:
I don't think the shared axis stuff is quite what I want.
My top and bottom plot have very different scales, so when I share the axes, it shifts the scaling too. For example, say my top plot has data that runs from 0-100 on the x axis and on the bottom plot the data runs from 0-50. When I share the axis, the top plot only shows data from 0-50, which I don't want it to.
I want it to show from 0-100 as it did before, but just want it to share the axis and gridlines from the other plot.
You could use LinearLocator:
from matplotlib.ticker import LinearLocator
Then on each of your x-axis or only on one of them call:
N = 6 # Set number of gridlines you want to have in each graph
ax1.xaxis.set_major_locator(LinearLocator(N))
ax2.xaxis.set_major_locator(LinearLocator(N))
Or get the number of ticks from your source axis and set it on target axis:
N = source_ax.xaxis.get_major_ticks()
target_ax.xaxis.set_major_locator(LinearLocator(N))

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.

Categories