1

I have tried and tried to search for a solution, but I can't seem to make it work, so here is my problem:

I am trying to make a script, where I can set a size (i.e. number of subplots in a figure) of the figure. It should always be a N*2 grid structure (with equal dimensions) for the subplots in the figure. In the grids, I want to plot some lines (with a specific color) and add a horizontal colorbar at the bottom of the figure. I have tried following the solution to the problem, mentioned in Matplotlib 2 Subplots, 1 Colorbar. Here is my solution:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import matplotlib.colors as colors
import matplotlib.cm as cmx
import random

lines = np.random.rand(100, 10)
fig, ax = plt.subplots(nrows=2,ncols=2, sharex=True)
ranks = np.linspace(0,len(lines[0,:]), len(lines[0,:]))
norm = matplotlib.colors.Normalize(
    vmin=np.min(ranks),
    vmax=np.max(ranks))

c_m = matplotlib.cm.cool
s_m = matplotlib.cm.ScalarMappable(cmap=c_m, norm=norm)
s_m.set_array([])


for line, rank in zip(xrange(0,len(lines[0,:])), ranks):

    try:
        no = random.randint(0,1)
        no2 =random.randint(0,1)
        im =ax[no,no2].plot(lines[:, line], c=s_m.to_rgba(rank))
    except IOError as error:
        print error

fig.subplots_adjust(bottom=0.2)
fig.colorbar(s_m, orientation='horizontal')
plt.show()

So my question is: How do I make a gridbased subplot (for line- and scatterplots), where I can add one colorbar horizontally at the bottom to stretch across both subplots in the bottom?

kch197
  • 39
  • 7
  • 1
    What is the colorbar supposed to show? The first argument to `fig.colorbar` (`ax[1,1]`) is wrong. If you type `help(fig.colorbar)` you see that you need to provide a `mappable` as first argument (like, for instance, the return value of `ax.imshow`). What you want to provide as `ax[1,1]` is probably `cax`, i.e. the axes to which the colorbar should be attached. – Thomas Kühn Jan 23 '18 at 10:21
  • 1
    It would help tremendously if you provided a [mcve], instead of some datafile which we don't have. From that it would be more obvious what you are trying to achieve here. Also clearly explain what the colorbar should actually show - what is the mapping you want to display? – ImportanceOfBeingErnest Jan 23 '18 at 10:25

2 Answers2

1

You should provide the ax argument to the colorbar function,

fig.colorbar(s_m, ax = ax.flatten(), orientation='horizontal')

This would then produce

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
1

So I figured it out and both Thomas Kühn and and ImportanceOfBeingErnest helped me see the errors:

First off, I changed the question to be replicable and with a mappable instead of ax[1,1]. Once doing that, I could see how it was actually directly transferrable to the question I had linked to, in my question. Here is my result:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import matplotlib.colors as colors
import matplotlib.cm as cmx
import os
import random


fnames = np.random.rand(100, 10)
fig, ax = plt.subplots(nrows=2,ncols=2, sharex=True, figsize=(4,4))
parameters = np.linspace(0,len(fnames[0,:]), len(fnames[0,:]))

norm = matplotlib.colors.Normalize(
    vmin=np.min(parameters),
    vmax=np.max(parameters))

c_m = matplotlib.cm.cool
s_m = matplotlib.cm.ScalarMappable(cmap=c_m, norm=norm)
s_m.set_array([])

for filename, parameter in zip(xrange(0,len(fnames[0,:])), parameters):
    try:
        no = random.randint(0,1)
        no2 =random.randint(0,1)
        ax[no,no2].plot(fnames[:, filename], c=s_m.to_rgba(parameter))
    except IOError as error:
        print error
for ax1 in ax.flatten():
    ax1.set_xlabel('Y')
    ax1.set_ylabel('X')
plt.title('Title')
fig.subplots_adjust(bottom=0.2)
cbar_ax = fig.add_axes([0.13, 0.08, 0.74, 0.03])
cbar = fig.colorbar(s_m, cax=cbar_ax, orientation='horizontal')
cbar.set_label('Focus: ')
plt.show()

Which gave this plot. Thanks for the tips. Would you recommend changing the grid structure from plt.subplots, to AxesGrid, found in mpl_toolkits.axes_grid1?

enter image description here

kch197
  • 39
  • 7
  • I would not recomment using `mpl_toolkits.axes_grid1` unless you need to. – ImportanceOfBeingErnest Jan 23 '18 at 12:23
  • Why? Is it slower than the other method? – kch197 Jan 24 '18 at 11:47
  • Experience tells that very often things turn out to become very complicated when using `mpl_toolkits.axes_grid1` or unexpected outcomes happen. So if you can achieve what you want using normal subplots, that would be the way to go. For special cases as e.g. showing images, axisgrid may give you an easier solution out of the box though. – ImportanceOfBeingErnest Jan 24 '18 at 11:52