1

There have been other questions about it but none seems to cover my exact question / none of their solutions "corrected" my problem.

import matplotlib.pyplot as plt
calendar = [[1,0,0,1,1,0,1],[0,0,1,1,1,0,1]]
fig, ax = plt.subplots()
namelist = ['alpha','beta']
yticks = [n for n in range(len(namelist))]
ax.set_yticks(yticks)
ax.set_yticklabels(namelist)
ax2 = ax.twinx()
ax2.set_yticks(ax.get_yticks())
ax2.set_yticklabels(['gamma','delta'])    

im = ax.imshow(calendar, interpolation='none', cmap='summer')
plt.show()

enter image description here

Of course the upper is just a very simplified version but it should be enough to see the problem: When commenting out the two "ax2 lines" the plot is as I want but when adding the second y-axis the plot resizes like I don't want it. I want the alpha/beta to be at the same height as gamma/delta (such that no white space is remaining) but I'm failing for quite some time now. I've tried the get_yticks() function (as proposed in some similar questions) but it didn't help. Thanks in advance!

EDIT: One small detail: The solution should be "extendible" in the sense, that it should handle more y-values (alpha, beta, delta, ...) with their twin counterpart in front.

EDIT 2: (I wasn't sure if posting a new question was useful, so I just ask here:) I'm now trying to add a grid. I've again tried a lot but nothing seems to help, at best I can get a y-axis-grid. Check the following code (and try the same with those lines uncommented!):

import matplotlib.pyplot as plt
calendar = [[1,0,0,1,1,0,1],[0,0,1,1,1,0,1]]
fig, ax = plt.subplots()
namelist = ['alpha','beta']
yticks = [n for n in range(len(namelist))]
ax.set_xticks([num for num in range(len(calendar[0]))])
ax.set_xticks([num-0.5 for num in range(len(calendar[0]))],minor=True)
ax.set_yticks(yticks)
ax.set_yticks([num-0.5 for num in range(len(namelist))],minor=True)
ax.set_yticklabels(namelist)
im = ax.imshow(calendar, interpolation='none', cmap='summer')
ax.set_adjustable('box-forced')
ax.xaxis.grid(which='major',alpha=1,color='k',lw=2)
ax.xaxis.grid(which='minor',alpha=1,color='k',lw=2)
ax.yaxis.grid(which='minor',alpha=1,color='k',lw=2)

#ax2 = ax.twinx()
#ax2.set_yticks(ax.get_yticks())
#ax2.set_yticklabels(['gamma','delta'])    
#im2 = ax2.imshow(calendar, interpolation='none', cmap='summer')
#ax2.set_adjustable('box-forced')

plt.show()

How can I get the grid to show up? Here a picture of how it is (without ax2). Basically shouldn't the code exactly give me the same but with the second label(s) on the right?! enter image description here

famfop
  • 185
  • 1
  • 1
  • 9

1 Answers1

2

One way to get what you want is to re-plot on ax2:

im2 = ax2.imshow(calendar, interpolation='none', cmap='summer')

It's not perfect, but it works.

ticks in correct positions

EDIT:

Following the answer here, if you further use set_adjustable on your axes, the whitespace disappears:

import matplotlib.pyplot as plt
calendar = [[1,0,0,1,1,0,1],[0,0,1,1,1,0,1]]
fig, ax = plt.subplots()
namelist = ['alpha','beta']
yticks = [n for n in range(len(namelist))]
ax.set_yticks(yticks)
ax.set_yticklabels(namelist)
im = ax.imshow(calendar, interpolation='none', cmap='summer')
ax.set_adjustable('box-forced')

ax2 = ax.twinx()
ax2.set_yticks(ax.get_yticks())
ax2.set_yticklabels(['gamma','delta'])    
im2 = ax2.imshow(calendar, interpolation='none', cmap='summer')
ax2.set_adjustable('box-forced')

plt.show()

whitespace removed

Thomas Kühn
  • 9,412
  • 3
  • 47
  • 63
  • Thanks, this helped me already but it's still not solving the problem of the white space above and below the green/yellow part. – famfop Aug 01 '17 at 19:33
  • I ran into a problem closely related to the previous and edited my question. I would be great if you could help me out with this last detail :) – famfop Aug 02 '17 at 16:41
  • @famfop As in my solution you basically plot everything twice, `ax2` is drawn on top of `ax`, so any modifications you do to the plot in `ax` is invisible -- try setting the grid to `ax2`. – Thomas Kühn Aug 02 '17 at 16:44
  • I also tried that! But it didn't yield the effect. Even if I only put a `ax2.grid(True)` it only gives me a y-axis-grid... – famfop Aug 02 '17 at 17:15
  • got it! I solved it by "preparing" everything on ax1 and then setting the zorder > 0 `ax1.set_zorder(1)` as proposed [here][1] by Jon Hunter. [1]: http://matplotlib.1069221.n5.nabble.com/onpick-on-a-2-y-plot-via-twinx-seems-to-only-allow-picking-of-second-axes-s-artists-td6421.html – famfop Aug 02 '17 at 18:22
  • @famop perfect! I had been looking quite a while without success. – Thomas Kühn Aug 02 '17 at 18:52
  • It seems that this solution is broken in 2023, since `box-forced` is no longer an accepted value. See [this new thread](https://stackoverflow.com/questions/76302149/matplotlib-imshow-with-twinx-that-is-also-aligned-with-tiles). – Mew May 21 '23 at 22:43