Reputation: 1331
I am trying to show a matrix and a related vector data together using matplotlib matshow.
vec_data = np.array([[ 0., 1., 1., 1., 0., 1., 1., 0., 0., 0.]])
mat_data = np.array([
[ 0. , 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 1. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0.5, 0. , 0.5, 0. , 0. , 0. , 0. ],
[ 0. , 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1, 0.1, 0. , 0.1],
[ 0. , 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1],
[ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. , 0. ],
[ 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1, 0.1, 0.1, 0. ]])
fig, axes = plt.subplots(2,1,figsize=(4,4),sharey=False,sharex=True,gridspec_kw = {'height_ratios':[25,1]})
axes[0].matshow(mat_data)
axes[1].matshow(vec_data)
axes[1].tick_params(direction='out', length=6, width=0)
axes[1].set_yticklabels([''])
axes[1].set_xlabel('vector')
The resulting image would be as follows:
The issue here is that when putting these two matshow images together mess up the ylim of the first image: it is supposed to show the values from 0 to 9, but it only shows a range 0.5 to 8.5. If I plot the image alone with the command
plt.matshow(mat_data)
I get the desired image with correct ylim.
Anybody knows what causes the issue and how I can fix it? I tried to use
axes[0].set_ylim([-0.5,9.5])
but it does not work.
P.S.: I have used the keyword gridspec_kw = {'height_ratios':[25,1]} so that the vector is shown as a vector--otherwise it will be shown as a matrix with blank values like the following.
The argument sharex = True is used for plt.subplots in order for the vector and the matrix to be aligned. Without the argument, the graph will be like the following
but note there that the issue with the ylim is gone--so it is possible that the argument is the main cause of this issue. I guess if I can find another way to align the two images without using "sharex = True" can solve this issue.
Upvotes: 1
Views: 925
Reputation: 339340
Using sharex=True
for the subplots overconstrains the system. Matplotlib will hence free the plot limits to be able to show the plot with the given specifications.
The solution would be to use sharex=False
(the default). Then the height-ratios need to match the dimensions of the images, i.e.
fig, axes = plt.subplots(2,1,figsize=(4,4),sharey=False,sharex=False,
gridspec_kw = {'height_ratios':[mat_data.shape[0],vec_data.shape[0]]})
Complete example:
import numpy as np
import matplotlib.pyplot as plt
vec_data = np.array([[ 0., 1., 1., 1., 0., 1., 1., 0., 0., 0.]])
mat_data = np.random.choice([0,.1,.5,1], size=(10,10))
fig, axes = plt.subplots(2,1,figsize=(4,4),sharey=False,sharex=False,
gridspec_kw = {'height_ratios':[mat_data.shape[0],vec_data.shape[0]]})
axes[0].matshow(mat_data)
axes[1].matshow(vec_data)
axes[1].tick_params(direction='out', length=6, width=0)
axes[1].set_yticklabels([''])
axes[1].set_xlabel('vector')
plt.show()
Upvotes: 2