Rotation of colorbar tick labels in matplotlib - python

I would like to rotate the colorbar tick labels so that they read vertically rather than horizontally. I have tried as many variations as I can think of with cbar.ax.set_xticklabels and cbar.ax.ticklabel_format and so on with rotation='vertical' but haven't quite landed it yet.
I've provided a MWE below:
import numpy as np
import matplotlib.pyplot as plt
#example function
x,y = np.meshgrid(np.linspace(-10,10,200),np.linspace(-10,10,200))
z = x*y*np.exp(-(x+y)**2)
#array for contourf levels
clevs = np.linspace(z.min(),z.max(),50)
#array for colorbar tick labels
clevs1 =np.arange(-200,100,10)
cs1 = plt.contourf(x,y,z,clevs)
cbar = plt.colorbar(cs1, orientation="horizontal")
cbar.set_ticks(clevs1[::1])
plt.show()
Any pointers would be greatly appreciated - I'm sure this must be pretty simple...

If you're happy with tick locations and labels and only want to rotate them:
cbar.ax.set_xticklabels(cbar.ax.get_xticklabels(), rotation='vertical')

This is the idiomatic way to rotate tick labels as of Matplotlib 3.4 (and very likely earlier versions too)
cbar.ax.tick_params(rotation=45)

You can use cbar.ax.set_xticklabels to change the rotation (or set_yicklabels if you had a vertical colorbar).
cbar.ax.set_xticklabels(clevs1[::1],rotation=90)
EDIT:
To set the ticks correctly, you can search for where in your clevs1 array the first tick should be using np.argmin, and use that to index clevs1 when you set_xticklabels:
tick_start = np.argmin(abs(clevs1-clevs[0]))
cbar.ax.set_xticklabels(clevs1[tick_start:],rotation=90)

Related

Setting yticks Location Matplotlib

I'm trying to create a plot which has y axis exactly same with this :
And I'm in this situation and everything is ok until this point:
When i try this lines:
ax.set_yticks(range(20,67,10))
ax.set_yticklabels(['20','30','40','50','60'])
My graph is becoming this:
I couldn't understand how to set locations' of yticks properly.
Have you tried the following?
import numpy as np
ticks = np.linspace(20, 60, 5)
ax.set_yticks(ticks)
ax.set_yticklabels([str(int(x)) for x in ticks])
If you want numbers on the axes, make sure you plot numbers, not strings. The axis labels would then adjust automatically as desired, or you may use set_yticks and set_yticklabels as in the question.

Matplotlib delete plot stribes

I have the following issue displayed in the image below:
For an improved clarity I want do delete the stripes on the x axis or put them below the x axis. (Also it would be nice If you know a solution to the problem of overlapping numbers)
Assuming you have defined your plot and axes as below:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
If you want to remove the x axis tick marks you can do:
ax.tick_params(axis='x', top='off', bottom='off')
If you want to change the direction of the tick marks you can do:
ax.tick_params(axis='x', direction='out')
If you want to change the x axis labels then use:
set_xticklabels()
You have to pass a list of labels to use, although I'm not sure why your labels aren't evenly spaced. The documentation at the link below should help:
matplotlib.axes documentation

Change distance between boxplots in the same figure in python [duplicate]

I'm drawing the bloxplot shown below using python and matplotlib. Is there any way I can reduce the distance between the two boxplots on the X axis?
This is the code that I'm using to get the figure above:
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['ytick.direction'] = 'out'
rcParams['xtick.direction'] = 'out'
fig = plt.figure()
xlabels = ["CG", "EG"]
ax = fig.add_subplot(111)
ax.boxplot([values_cg, values_eg])
ax.set_xticks(np.arange(len(xlabels))+1)
ax.set_xticklabels(xlabels, rotation=45, ha='right')
fig.subplots_adjust(bottom=0.3)
ylabels = yticks = np.linspace(0, 20, 5)
ax.set_yticks(yticks)
ax.set_yticklabels(ylabels)
ax.tick_params(axis='x', pad=10)
ax.tick_params(axis='y', pad=10)
plt.savefig(os.path.join(output_dir, "output.pdf"))
And this is an example closer to what I'd like to get visually (although I wouldn't mind if the boxplots were even a bit closer to each other):
You can either change the aspect ratio of plot or use the widths kwarg (doc) as such:
ax.boxplot([values_cg, values_eg], widths=1)
to make the boxes wider.
Try changing the aspect ratio using
ax.set_aspect(1.5) # or some other float
The larger then number, the narrower (and taller) the plot should be:
a circle will be stretched such that the height is num times the width. aspect=1 is the same as aspect=’equal’.
http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.set_aspect
When your code writes:
ax.set_xticks(np.arange(len(xlabels))+1)
You're putting the first box plot on 0 and the second one on 1 (event though you change the tick labels afterwards), just like in the second, "wanted" example you gave they are set on 1,2,3.
So i think an alternative solution would be to play with the xticks position and the xlim of the plot.
for example using
ax.set_xlim(-1.5,2.5)
would place them closer.
positions : array-like, optional
Sets the positions of the boxes. The ticks and limits are automatically set to match the positions. Defaults to range(1, N+1) where N is the number of boxes to be drawn.
https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.boxplot.html
This should do the job!
As #Stevie mentioned, you can use the positions kwarg (doc) to manually set the x-coordinates of the boxes:
ax.boxplot([values_cg, values_eg], positions=[1, 1.3])

Overlapping y-axis tick label and x-axis tick label in matplotlib

If I create a plot with matplotlib using the following code:
import numpy as np
from matplotlib import pyplot as plt
xx = np.arange(0,5, .5)
yy = np.random.random( len(xx) )
plt.plot(xx,yy)
plt.imshow()
I get a result that looks like the attached image. The problem is the
bottom-most y-tick label overlaps the left-most x-tick label. This
looks unprofessional. I was wondering if there was an automatic
way to delete the bottom-most y-tick label, so I don't have
the overlap problem. The fewer lines of code, the better.
In the ticker module there is a class called MaxNLocator that can take a prune kwarg.
Using that you can remove the first tick:
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
import numpy as np
xx = np.arange(0,5, .5)
yy = np.random.random( len(xx) )
plt.plot(xx,yy)
plt.gca().xaxis.set_major_locator(MaxNLocator(prune='lower'))
plt.show()
Result:
You can pad the ticks on the x-axis:
ax.tick_params(axis='x', pad=15)
Replace ax with plt.gca() if you haven't stored the variable ax for the current figure.
You can also pad both the axes removing the axis parameter.
A very elegant way to fix the overlapping problem is increasing the padding of the x- and y-tick labels (i.e. the distance to the axis). Leaving out the corner most label might not always be wanted. In my opinion, in general it looks nice if the labels are a little bit farther from the axis than given by the default configuration.
The padding can be changed via the matplotlibrc file or in your plot script by using the commands
import matplotlib as mpl
mpl.rcParams['xtick.major.pad'] = 8
mpl.rcParams['ytick.major.pad'] = 8
Most times, a padding of 6 is also sufficient.
This is answered in detail here. Basically, you use something like this:
plt.xticks([list of tick locations], [list of tick lables])

rotating xticks causes the ticks partially hidden in matplotlib

I am creating a plot with names on x axis and time values(minutes) on y axis.The names on x axis are like
['cooking']18:15:27 ,['study']18:09:19,['travel']18:21:34` etc ..
where as the y values are 5,1,1 etc.I have given xlabel as 'categories' and ylabel as 'durations in minutes'.
Since the xticks were strings of some length,I decided to rotate them by 90 to avoid overlapping.Now ,the ticks are partially hidden and the xlabel has disappeared.
Is there some way I can make the whole plot accommodate everything..?
thanks
mark
here is the code snippet
import matplotlib.pyplot as plt
...
figure = plt.figure()
barwidth = 0.25
ystep = 10
plt.grid(True)
plt.xlabel('categories')
plt.ylabel('durations in minutes')
plt.title('durations for categories-created at :'+now)
plt.bar(xdata, ydata, width=barwidth,align='center')
plt.xticks(xdata,catnames,rotation=90)
plt.yticks(range(0,maxduration+ystep,ystep))
plt.xlim([min(xdata) - 0.5, max(xdata) + 0.5])
plt.ylim(0,max(ydata)+ystep)
figure.savefig("myplot.png",format="png")
plt.tight_layout()
But be sure to add this command after plt.plot() or plt.bar()
One good option is to rotate the tick labels.
In your specific case, you might find it convenient to use figure.autofmt_xdate() (Which will rotate the x-axis labels among other things).
Alternatively, you could do plt.setp(plt.xticks()[1], rotation=30) (or various other ways of doing the same thing).
Also, as a several year later edit, with recent versions of matplotlib, you can call fig.tight_layout() to resize things to fit the labels inside the figure, as #elgehelge notes below.
Setting the bounding box when saving will also show the labels:
figure.savefig('myplot.png', bbox_inches='tight')

Categories

Resources