4

I'm currently using matplotlib within Sage to plot some data. I have made it possible to add multiple y axes using this example:

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt

if 1:

    host = host_subplot(111, axes_class=AA.Axes)
    plt.subplots_adjust(right=0.75)

    par1 = host.twinx()
    par2 = host.twinx()

    offset = 60
    new_fixed_axis = par2.get_grid_helper().new_fixed_axis
    par2.axis["right"] = new_fixed_axis(loc="right",
                                        axes=par2,
                                        offset=(offset, 0))

    par2.axis["right"].toggle(all=True)



    host.set_xlim(0, 2)
    host.set_ylim(0, 2)

    host.set_xlabel("Distance")
    host.set_ylabel("Density")
    par1.set_ylabel("Temperature")
    par2.set_ylabel("Velocity")

    p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
    p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
    p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")

    par1.set_ylim(0, 4)
    par2.set_ylim(1, 65)

    host.legend()

    host.axis["left"].label.set_color(p1.get_color())
    par1.axis["right"].label.set_color(p2.get_color())
    par2.axis["right"].label.set_color(p3.get_color())

    plt.draw()
    plt.show()

    #plt.savefig("Test")

source: http://matplotlib.org/examples/axes_grid/demo_parasite_axes2.html

However, is it possible to change the colour of the parasite axes? I read somewhere that this method is not very compatible with the original twinx() so that may be complicating things.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
MEvans
  • 301
  • 1
  • 3
  • 8

1 Answers1

21

Its not necessary to use the AA class, although normally that would save you a few lines of code. I'm not sure what exactly you want to color since the axes consists of many items which can have a color like spines, label, ticklabels etc.

This example shows how to color most of it, its almost identical to the one in the gallery.

import matplotlib.pyplot as plt

fig, host = plt.subplots()
fig.subplots_adjust(right=0.75)

par1 = host.twinx()
par2 = host.twinx()

# move the spine of the second axes outwards
par2.spines["right"].set_position(("axes", 1.2))

p1, = host.plot([0, 1, 2], [0, 1, 2], 'r-', label="Density")
p2, = par1.plot([0, 1, 2], [0, 3, 2], 'g-', label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], 'b-', label="Velocity")

host.set_xlim(0, 2)
host.set_ylim(0, 2)
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)

host.set_xlabel("Distance")
host.set_ylabel("Density")
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")

lines = [p1, p2, p3]
host.legend(lines, [l.get_label() for l in lines])

for ax in [par1, par2]:
    ax.set_frame_on(True)
    ax.patch.set_visible(False)

    plt.setp(ax.spines.values(), visible=False)
    ax.spines["right"].set_visible(True)

host.yaxis.label.set_color(p1.get_color())
par1.yaxis.label.set_color(p2.get_color())
par2.yaxis.label.set_color(p3.get_color())

par1.spines["right"].set_edgecolor(p2.get_color())
par2.spines["right"].set_edgecolor(p3.get_color())

host.tick_params(axis='y', colors=p1.get_color())
par1.tick_params(axis='y', colors=p2.get_color())
par2.tick_params(axis='y', colors=p3.get_color())

enter image description here

Rutger Kassies
  • 61,630
  • 17
  • 112
  • 97
  • 1
    Thanks for the reply. I had tried this method previously but gave up when I couldn't get it to work for an arbitrary amount of y axes. What I want is a function that plots a user-specified number of y axes (corresponding to what the user wants to plot) and offsets them and colors every part of the axes automatically. I've tried using an array to store the axes but only the last one shows. DO you know how I can achieve this? – MEvans Dec 06 '13 at 16:38
  • I've figured it out. For some reason using host.twinx() multiple times doesn't work for me- maybe that's a newer feature of matplotlib? (I believe I am using an older version but it's beyond my control to upgrade). So instead I'm using the previous axes for each new twinx() in a for loop and it all seems to be working perfectly. – MEvans Dec 09 '13 at 16:48
  • 5
    If you want to change host's y-axis color, cause `host.spines['left'].set_color('red)` seems not working. This is because it is blocked by par1 or par2 whichever is later. So if you want to change the left y-axis to color red, you could add this at the end `par2.spines['left'].set_color('red')` – Jason May 08 '20 at 09:21