Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib: adding second axes() with transparent background?

Define data

x = np.linspace(0,2*np.pi,100)
y = 2*np.sin(x)

Plot

fig = plt.figure()
ax = plt.axes()
fig.add_subplot(ax)
ax.plot(x,y)

Add second axis

newax = plt.axes(axisbg='none')

Gives me ValueError: Unknown element o, even though it does the same thing as what I am about to describe. I can also see that this works (no error) to do the same thing:

newax = plt.axes()
fig.add_subplot(newax)
newax.set_axis_bgcolor('none')

However, it turns the background color of the original figure "gray" (or whatever the figure background is)? I don't understand, as I thought this would make newax transparent except for the axes and box around the figure. Even if I switch the order, same thing:

plt.close('all')
fig = plt.figure()
newax = plt.axes()
fig.add_subplot(newax)
newax.set_axis_bgcolor('none')
ax = plt.axes()
fig.add_subplot(ax)
ax.plot(x,y)

This is surprising because I thought the background of one would be overlaid on the other, but in either case it is the newax background that appears to be visible (or at least this is the color I see).

What is going on here?

like image 601
hatmatrix Avatar asked Oct 13 '11 23:10

hatmatrix


People also ask

How do I make the background transparent in MatPlotLib?

If you just want the entire background for both the figure and the axes to be transparent, you can simply specify transparent=True when saving the figure with fig. savefig . If you want more fine-grained control, you can simply set the facecolor and/or alpha values for the figure and axes background patch.

What is the function of YLIM () in MatPlotLib?

ylim() Function. The ylim() function in pyplot module of matplotlib library is used to get or set the y-limits of the current axes.

What is PLT CLA ()?

The cla() function in pyplot module of matplotlib library is used to clear the current axes. Syntax: matplotlib.pyplot.cla()


1 Answers

You're not actually adding a new axes.

Matplotlib is detecting that there's already a plot in that position and returning it instead of a new axes object.

(Check it for yourself. ax and newax will be the same object.)

There's probably not a reason why you'd want to, but here's how you'd do it.

(Also, don't call newax = plt.axes() and then call fig.add_subplot(newax) You're doing the same thing twice.)

Edit: With newer (>=1.2, I think?) versions of matplotlib, you can accomplish the same thing as the example below by using the label kwarg to fig.add_subplot. E.g. newax = fig.add_subplot(111, label='some unique string')

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

# If you just call `plt.axes()` or equivalently `fig.add_subplot()` matplotlib  
# will just return `ax` again. It _won't_ create a new axis unless we
# call fig.add_axes() or reset fig._seen
newax = fig.add_axes(ax.get_position(), frameon=False)

ax.plot(range(10), 'r-')
newax.plot(range(50), 'g-')
newax.axis('equal')

plt.show()

enter image description here

Of course, this looks awful, but it's what you're asking for...

I'm guessing from your earlier questions that you just want to add a second x-axis? If so, this is a completely different thing.

If you want the y-axes linked, then do something like this (somewhat verbose...):

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
newax = ax.twiny()

# Make some room at the bottom
fig.subplots_adjust(bottom=0.20)

# I'm guessing you want them both on the bottom...
newax.set_frame_on(True)
newax.patch.set_visible(False)
newax.xaxis.set_ticks_position('bottom')
newax.xaxis.set_label_position('bottom')
newax.spines['bottom'].set_position(('outward', 40))

ax.plot(range(10), 'r-')
newax.plot(range(21), 'g-')

ax.set_xlabel('Red Thing')
newax.set_xlabel('Green Thing')

plt.show()

enter image description here

If you want to have a hidden, unlinked y-axis, and an entirely new x-axis, then you'd do something like this:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)

newax = fig.add_axes(ax.get_position())
newax.patch.set_visible(False)
newax.yaxis.set_visible(False)

for spinename, spine in newax.spines.iteritems():
    if spinename != 'bottom':
        spine.set_visible(False)

newax.spines['bottom'].set_position(('outward', 25))

ax.plot(range(10), 'r-')

x = np.linspace(0, 6*np.pi)
newax.plot(x, 0.001 * np.cos(x), 'g-')

plt.show()

enter image description here

Note that the y-axis values for anything plotted on newax are never shown.

If you wanted, you could even take this one step further, and have independent x and y axes (I'm not quite sure what the point of it would be, but it looks neat...):

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2, right=0.85)

newax = fig.add_axes(ax.get_position())
newax.patch.set_visible(False)

newax.yaxis.set_label_position('right')
newax.yaxis.set_ticks_position('right')

newax.spines['bottom'].set_position(('outward', 35))

ax.plot(range(10), 'r-')
ax.set_xlabel('Red X-axis', color='red')
ax.set_ylabel('Red Y-axis', color='red')

x = np.linspace(0, 6*np.pi)
newax.plot(x, 0.001 * np.cos(x), 'g-')

newax.set_xlabel('Green X-axis', color='green')
newax.set_ylabel('Green Y-axis', color='green')


plt.show()

enter image description here

You can also just add an extra spine at the bottom of the plot. Sometimes this is easier, especially if you don't want ticks or numerical things along it. Not to plug one of my own answers too much, but there's an example of that here: How do I plot multiple X or Y axes in matplotlib?

As one last thing, be sure to look at the parasite axes examples if you want to have the different x and y axes linked through a specific transformation.

like image 186
Joe Kington Avatar answered Oct 16 '22 22:10

Joe Kington