Matplotlib: changing font size of exponent - matplotlib

I want to change the fontsize of the exponent as marked on the picture
I cannot use the matplotlib.rc('font', **font) method since I have different plots that need different font sizes so I change every element individually. I can however not find the font properties of the exponent.

If the exponent is an offset computed by matplotlib you can do the following to change the font size of the exponent to 30
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(1,1.0001,100)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x)
t = ax.yaxis.get_offset_text()
t.set_size(30)
plt.show()

Related

AttributeError when trying to change tittle and axis size matplotlib [duplicate]

I am creating a figure in Matplotlib like this:
from matplotlib import pyplot as plt
fig = plt.figure()
plt.plot(data)
fig.suptitle('test title')
plt.xlabel('xlabel')
plt.ylabel('ylabel')
fig.savefig('test.jpg')
I want to specify font sizes for the figure title and the axis labels. I need all three to be different font sizes, so setting a global font size (mpl.rcParams['font.size']=x) is not what I want. How do I set font sizes for the figure title and the axis labels individually?
Functions dealing with text like label, title, etc. accept parameters same as matplotlib.text.Text. For the font size you can use size/fontsize:
from matplotlib import pyplot as plt
fig = plt.figure()
plt.plot(data)
fig.suptitle('test title', fontsize=20)
plt.xlabel('xlabel', fontsize=18)
plt.ylabel('ylabel', fontsize=16)
fig.savefig('test.jpg')
For globally setting title and label sizes, mpl.rcParams contains axes.titlesize and axes.labelsize. (From the page):
axes.titlesize : large # fontsize of the axes title
axes.labelsize : medium # fontsize of the x any y labels
(As far as I can see, there is no way to set x and y label sizes separately.)
And I see that axes.titlesize does not affect suptitle. I guess, you need to set that manually.
You can also do this globally via a rcParams dictionary:
import matplotlib.pylab as pylab
params = {'legend.fontsize': 'x-large',
'figure.figsize': (15, 5),
'axes.labelsize': 'x-large',
'axes.titlesize':'x-large',
'xtick.labelsize':'x-large',
'ytick.labelsize':'x-large'}
pylab.rcParams.update(params)
If you're more used to using ax objects to do your plotting, you might find the ax.xaxis.label.set_size() easier to remember, or at least easier to find using tab in an ipython terminal. It seems to need a redraw operation after to see the effect. For example:
import matplotlib.pyplot as plt
# set up a plot with dummy data
fig, ax = plt.subplots()
x = [0, 1, 2]
y = [0, 3, 9]
ax.plot(x,y)
# title and labels, setting initial sizes
fig.suptitle('test title', fontsize=12)
ax.set_xlabel('xlabel', fontsize=10)
ax.set_ylabel('ylabel', fontsize='medium') # relative to plt.rcParams['font.size']
# setting label sizes after creation
ax.xaxis.label.set_size(20)
plt.draw()
I don't know of a similar way to set the suptitle size after it's created.
To only modify the title's font (and not the font of the axis) I used this:
import matplotlib.pyplot as plt
fig = plt.Figure()
ax = fig.add_subplot(111)
ax.set_title('My Title', fontdict={'fontsize': 8, 'fontweight': 'medium'})
The fontdict accepts all kwargs from matplotlib.text.Text.
Per the official guide, use of pylab is no longer recommended. matplotlib.pyplot should be used directly instead.
Globally setting font sizes via rcParams should be done with
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 16
plt.rcParams['axes.titlesize'] = 16
# or
params = {'axes.labelsize': 16,
'axes.titlesize': 16}
plt.rcParams.update(params)
# or
import matplotlib as mpl
mpl.rc('axes', labelsize=16, titlesize=16)
# or
axes = {'labelsize': 16,
'titlesize': 16}
mpl.rc('axes', **axes)
The defaults can be restored using
plt.rcParams.update(plt.rcParamsDefault)
You can also do this by creating a style sheet in the stylelib directory under the matplotlib configuration directory (you can get your configuration directory from matplotlib.get_configdir()). The style sheet format is
axes.labelsize: 16
axes.titlesize: 16
If you have a style sheet at /path/to/mpl_configdir/stylelib/mystyle.mplstyle then you can use it via
plt.style.use('mystyle')
# or, for a single section
with plt.style.context('mystyle'):
# ...
You can also create (or modify) a matplotlibrc file which shares the format
axes.labelsize = 16
axes.titlesize = 16
Depending on which matplotlibrc file you modify these changes will be used for only the current working directory, for all working directories which do not have a matplotlibrc file, or for all working directories which do not have a matplotlibrc file and where no other matplotlibrc file has been specified. See this section of the customizing matplotlib page for more details.
A complete list of the rcParams keys can be retrieved via plt.rcParams.keys(), but for adjusting font sizes you have (italics quoted from here)
axes.labelsize - Fontsize of the x and y labels
axes.titlesize - Fontsize of the axes title
figure.titlesize - Size of the figure title (Figure.suptitle())
xtick.labelsize - Fontsize of the tick labels
ytick.labelsize - Fontsize of the tick labels
legend.fontsize - Fontsize for legends (plt.legend(), fig.legend())
legend.title_fontsize - Fontsize for legend titles, None sets to the same as the default axes. See this answer for usage example.
all of which accept string sizes {'xx-small', 'x-small', 'smaller', 'small', 'medium', 'large', 'larger', 'x-large', 'xxlarge'} or a float in pt. The string sizes are defined relative to the default font size which is specified by
font.size - the default font size for text, given in pts. 10 pt is the standard value
Additionally, the weight can be specified (though only for the default it appears) by
font.weight - The default weight of the font used by text.Text. Accepts {100, 200, 300, 400, 500, 600, 700, 800, 900} or 'normal' (400), 'bold' (700), 'lighter', and 'bolder' (relative with respect to current weight).
If you aren't explicitly creating figure and axis objects you can set the title fontsize when you create the title with the fontdict argument.
You can set and the x and y label fontsizes separately when you create the x and y labels with the fontsize argument.
For example:
plt.title('Car Prices are Increasing', fontdict={'fontsize':20})
plt.xlabel('Year', fontsize=18)
plt.ylabel('Price', fontsize=16)
Works with seaborn and pandas plotting (when Matplotlib is the backend), too!
Others have provided answers for how to change the title size, but as for the axes tick label size, you can also use the set_tick_params method.
E.g., to make the x-axis tick label size small:
ax.xaxis.set_tick_params(labelsize='small')
or, to make the y-axis tick label large:
ax.yaxis.set_tick_params(labelsize='large')
You can also enter the labelsize as a float, or any of the following string options: 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', or 'xx-large'.
An alternative solution to changing the font size is to change the padding. When Python saves your PNG, you can change the layout using the dialogue box that opens. The spacing between the axes, padding if you like can be altered at this stage.
Place right_ax before set_ylabel()
ax.right_ax.set_ylabel('AB scale')
libraries
import numpy as np
import matplotlib.pyplot as plt
create dataset
height = [3, 12, 5, 18, 45]
bars = ('A', 'B', 'C', 'D', 'E')
x_pos = np.arange(len(bars))
Create bars and choose color
plt.bar(x_pos, height, color = (0.5,0.1,0.5,0.6))
Add title and axis names
plt.title('My title')
plt.xlabel('categories')
plt.ylabel('values')
Create names on the x axis
plt.xticks(x_pos, bars)
Show plot
plt.show()
7 (best solution)
from numpy import*
import matplotlib.pyplot as plt
X = linspace(-pi, pi, 1000)
class Crtaj:
def nacrtaj(self,x,y):
self.x=x
self.y=y
return plt.plot (x,y,"om")
def oznaci(self):
return plt.xlabel("x-os"), plt.ylabel("y-os"), plt.grid(b=True)
6 (slightly worse solution)
from numpy import*
M = array([[3,2,3],[1,2,6]])
class AriSred(object):
def __init__(self,m):
self.m=m
def srednja(self):
redovi = len(M)
stupci = len (M[0])
lista=[]
a=0
suma=0
while a<stupci:
for i in range (0,redovi):
suma=suma+ M[i,a]
lista.append(suma)
a=a+1
suma=0
b=array(lista)
b=b/redovi
return b
OBJ = AriSred(M)
sr = OBJ.srednja()

display image with maximum width keeping an equal ratio

How to display an image with imshow on all the width of an axe (viewport) but keeping the ratio 'equal' ?
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(nrows=2, figsize=(8,8))
img = ax[0].imshow(np.random.random((10,10)), aspect='equal')
line = ax[1].plot([12,34],[45,78])
I would like that the image width be aligned on the line plot keeping an equal ratio even if that implies having blank around. My application has a zooming feature coded on the image in fact so I would to offer all the width possible for its display.
So in few words, I would like the same width as with aspect='auto' but with square pixels.
Is it possible ? Thanks.
Found with a reading of Axes class - set explicitly size (width/height) of axes in given units
and the use of
set_adjustable('datalim')
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(nrows=2, figsize=(8,8))
img = ax[0].imshow(np.random.random((10,10)), aspect='equal')
ax[0].set_adjustable('datalim')
line = ax[1].plot([12,34],[45,78])

matplotlib pyplot pcolor savefig colorbar transparency

I am trying to export a pcolor figure with a colorbar.
The cmap of the colorbar has a transparent color.
The exported figure has transparent colors in the axes but not in the colorbar. How can I fix this?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
x = np.random.random((10, 10))
colors = [(0,0,0,0), (0,0,0,1)]
cm = LinearSegmentedColormap.from_list('custom', colors, N=256, gamma=0)
plt.pcolor(x,cmap=cm)
plt.colorbar()
plt.savefig('figure.pdf',transparent=True)
I put the image against a grey background to check. As can be seen, the cmap in the axes is transparent while the one in the colorbar is not.
While the colorbar resides inside an axes, it has an additional background patch associated with it. This is white by default and will not be taken into account when transparent=True is used inside of savefig.
A solution is hence to remove the facecolor of this patch manually,
cb.patch.set_facecolor("none")
A complete example, which shows this without actually saving the figure
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
x = np.random.random((10, 10))
colors = [(1,1,1,0), (0,0,0,1)]
cm = LinearSegmentedColormap.from_list('custom', colors, N=256, gamma=0)
fig, ax = plt.subplots(facecolor="grey")
im = ax.pcolor(x,cmap=cm)
cb = fig.colorbar(im, drawedges=False)
ax.set_facecolor("none")
cb.patch.set_facecolor("none")
plt.show()

Consider sign in ytick label adjustment

When adding a colorbar to images plotting with matplotlib.pyplot.imshow, the colorbar's tick labels are normally placed to the right. If the value range spans positive and negative values, this leads to a misalignment between positive and negative values (positive values do not account for the '-' sign), which, IMHO, is very ugly.
How can I adjust this so that the tick labels are aligned properly?
import numpy as np
import matplotlib.pyplot as plt
data = np.random.rand(100, 100) - 0.5
plt.figure(figsize=(2,1.5))
img = plt.imshow(data)
cbar = plt.colorbar()
In order to have the positive and negative labels on the colorbar aligned, you may align the text to the right and increase the padding between axis and labels. The amount of padding to add will depend on the length of the ticklabels.
import numpy as np
import matplotlib.pyplot as plt
data = np.random.rand(100, 100) - 0.5
plt.figure()
img = plt.imshow(data)
cbar = plt.colorbar()
plt.setp(cbar.ax.get_yticklabels(), ha="right")
cbar.ax.tick_params(pad=30)
plt.show()
I'm not convinced that this looks better though.

Matplotlib colorbar and WCS projection

I'm trying to write a function to display astronomical images with a colorbar on the top (automaticly with the same length of the x-axis).
I'm having problem because when I try to put the tick on the top it doesn't do anything...it keeps the tick on the bottom of the colorbar (and also the tick on the y-axis of the colobar).
I think that could be a problem with the WCS coordinate of the x-axis, because when i try to do it without the projection it work well!
import numpy as np
import matplotlib.pyplot as plt
from astropy import wcs
from matplotlib.colors import PowerNorm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib import cm
#WCS coordinate system
w = wcs.WCS(naxis=2)
w.wcs.crpix = [23.5, 23.5]
w.wcs.cdelt = np.array([-0.0035, 0.0035])
w.wcs.crval = [266.8451, -28.151658]
w.wcs.ctype = ["RA---TAN", "DEC--TAN"]
w.wcs.set_pv([(2, 1, 45.0)])
#generate an array as image test
data = (np.arange(10000).reshape((100,100)))
#display image
fig = plt.figure()
ax = plt.gca(projection=w)
graf = ax.imshow(data, origin='lower', cmap=cm.viridis, norm=PowerNorm(1))
#colorbar
divider = make_axes_locatable(ax)
cax = divider.append_axes("top", size="5%")
cbar = fig.colorbar(graf, cax=cax, orientation='horizontal')
cax.xaxis.set_ticks_position('top')
fig.show()
Thanks!
You can fix this issue using matplotlib's axes class.
...
import matplotlib.axes as maxes
cax = divider.append_axes("top", size="5%", axes_class=maxes.Axes)
...
You need to use the internal machinery of the WCSAxes to handle the ticks in the WCS projection. It looks like WCSAxes handles the colorbar ticks through a coordinate map container (you can find it in cbar.ax.coords) instead of the xaxis/yaxis attributes (that don't seem to be used much).
So, after running your code, the following trick worked for me and the xticks moved up:
c_x = cbar.ax.coords['x']
c_x.set_ticklabel_position('t')
cbar.update_normal(cax)
To get something like this to work, I needed a few additional parameters:
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cax.coords[0].grid(False)
cax.coords[1].grid(False)
cax.tick_params(direction='in')
cax.coords[0].set_ticks(alpha=0, color='w', size=0, values=[]*u.dimensionless_unscaled)
cax.coords[1].set_ticklabel_position('r')
cax.coords[1].set_axislabel_position('r')
because the default axis gad the grid on, the labels to the left, and x-axis labels enabled. I'm not sure why the original post didn't have issues with this.