8

I am trying to plot 3 subplots without any white space between them. The default y axis ticklabels use a scale displayed to the top right of the y axis (1e-8 in the example below), which would be fine except for the lower two plots this overlaps with the plot above. Anyone know how to fix this? A small example is below.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib.ticker import MaxNLocator

x = np.arange(0,200)
y = np.random.rand(200) * 10e-8


fig = plt.figure(figsize=(10,15))
gs1 = gridspec.GridSpec(3, 3)
gs1.update(left=0.1, right=0.9, bottom=0.5, hspace=0.0)
ax0a = plt.subplot(gs1[0, :])
ax0b = plt.subplot(gs1[1, :])
ax0c = plt.subplot(gs1[2, :])


ax0a.set_xticklabels([])
ax0b.set_xticklabels([]) 

ax0a.plot(x,y)
nbins = len(ax0a.get_xticklabels())
ax0a.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))
ax0b.plot(x,y)
ax0b.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))
ax0c.plot(x,y)
ax0c.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))

plot

so one solution is to use mtick,

import matplotlib.ticker as mtick

ax0a.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1e'))
ax0b.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1e'))
ax0c.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1e'))

but I would prefer to be able to shift the scale to the left so it is outside the axis if possible.

1
  • Could you divide your data by 10e8, and just rename the xtick labels to r'$10^x$'? Commented Jun 11, 2015 at 4:12

2 Answers 2

7

I have two options you might want to look at.

First, set the axis location and size yourself as such:

# your imports and data above
fig = plt.figure()
ax0a = fig.add_axes([0.1, 0.1, 0.8, 0.25])
ax0b = fig.add_axes([0.1, 0.39, 0.8, 0.25], sharex=ax0a)
ax0c = fig.add_axes([0.1, 0.68, 0.8, 0.25], sharex=ax0a)
ax0a.set_xticklabels([])
ax0b.set_xticklabels([]) 
ax0a.plot(x,y)
nbins = len(ax0a.get_xticklabels())
ax0a.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))
ax0b.plot(x,y)
ax0b.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))
ax0c.plot(x,y)
ax0c.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))
plt.show()

enter image description here

The second option is to manually adjust the location and maybe font size of the offset text:

# your original code minus data and imports
fig = plt.figure()
gs1 = gridspec.GridSpec(3, 3)
gs1.update(left=0.1, right=0.9, bottom=0.5, hspace=0.0)
ax0a = plt.subplot(gs1[0, :])
ax0b = plt.subplot(gs1[1, :])
ax0c = plt.subplot(gs1[2, :])
ax0a.set_xticklabels([])
ax0b.set_xticklabels([]) 
ax0a.plot(x,y)
nbins = len(ax0a.get_xticklabels())
ax0a.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))
ax0b.plot(x,y)
ax0b.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))
ax0c.plot(x,y)
ax0c.yaxis.set_major_locator(MaxNLocator(nbins=nbins, prune='upper'))

# play around with location and font of offset text here
ax0a.get_yaxis().get_offset_text().set_x(-0.075)
ax0a.get_yaxis().get_offset_text().set_size(10)
ax0b.get_yaxis().get_offset_text().set_x(-0.075)
ax0b.get_yaxis().get_offset_text().set_size(10)
ax0c.get_yaxis().get_offset_text().set_x(-0.075)
ax0c.get_yaxis().get_offset_text().set_size(10)
plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Great! the second example is exactly what I need.
0

Ok, this is probably an ugly solution but you could just simply upscale your data in the lower plots with the range of the power i.e. ax0b.plot(x, y*1e8). This works for your example at least.

1 Comment

No I cant do it that way, I need to to keep it in the units it's already in, but thanks for the suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.