0

I am trying create two plots that should have the same width when displayed in a row-wise fashion. I have noticed that adding xticks followed by tight_layout makes the plot (pcolormesh) decrease in width from increasing the x-margins. I would like to move the ticks in such a way that the x-margins are eliminated and both pcolormesh have the same width.

I have the following example:

import numpy as np, matplotlib.pyplot as plt

def plot(ticks=True):
  fig, ax = plt.subplots(figsize=(6,1))

  np.random.seed(42)
  a = np.random.randn(1,6)
  ax.pcolormesh(a)

  plt.gca().invert_yaxis()
  ax.xaxis.tick_top()
  ax.set(yticklabels=[])
  ax.tick_params(left=False, length=5)

  if ticks:
    ax.set_xticks([0, 3, 6])
  else:
    plt.axis('off')

  plt.tight_layout()
  plt.savefig(f'plot-{ticks}.png', dpi=300, bbox_inches='tight', pad_inches=0.0)

I get the following plots when running with and without the ticks:

Without ticks

With ticks

The x-margins are not the same, which is more noticeable when increasing the font-size. How do I move the 3 label to right and the 6 label to the left to make both images have the same x-margins (0 margin)?

EDIT

Using the suggestion from Align specific x labels differently to each other? we have

import numpy as np, matplotlib.pyplot as plt

plt.rcParams.update({'font.size': 17})

fig, ax = plt.subplots(figsize=(6,1))

np.random.seed(42)
a = np.random.randn(1,6)
ax.pcolormesh(a)

plt.gca().invert_yaxis()
ax.xaxis.tick_top()
ax.set(yticklabels=[])
ax.tick_params(left=False, length=5)
# get list of x tick objects
xtick_objects = ax.xaxis.get_major_ticks()
xtick_objects[0].label1.set_horizontalalignment('left')   # left align first tick 
xtick_objects[-1].label1.set_horizontalalignment('right') # right align last tick

ax.set_xticks([0, 3, 6]) 

plt.tight_layout()
# plt.savefig(f'plot.png', dpi=300, bbox_inches='tight', pad_inches=0.0
plt.show()

which does not seem to change the alignment.

Kevin
  • 3,096
  • 2
  • 8
  • 37
  • Does this do it? https://stackoverflow.com/a/48196370/12133280 – pasnik Jun 04 '22 at 00:50
  • @pasnik It does not work for some reason, I edited the post. Setting the labels to `[" 0", 3, "6 "] but work, but I need to explicitly set the margins to 0 somehow, which I am not sure how to do. – Kevin Jun 04 '22 at 07:45
  • Since they are not comparable, I made a subplot so that we can compare them at the same time. deleting axis makes the graph a little smaller by eliminating pixels for the frame. Instead of deleting it, I changed the color of the graph frame. The resulting graph size appears to be identical, and I have expanded it to [Colab](https://colab.research.google.com/drive/1Psv0VpZvx5baoRY8S_Ul2m3jGtZtI6PI?usp=sharing) for reference. If you check this link, disable. – r-beginners Jun 04 '22 at 08:58
  • Thanks @r-beginners, this is a good idea. The discrepancy in width is caused by removing the axis with `plt.axis("off")` ? – Kevin Jun 04 '22 at 09:45
  • 1
    I will answer according to this content of mine. – r-beginners Jun 04 '22 at 09:52
  • Thanks for trying the example. I also cannot get it to work unless I remove `ax.xaxis.tick_top()`. The same is true for the example in the link that I shared. Because it works when the ticks are at the bottom but not at the top, I think it is a bug. If you can keep it at the bottom, your problem goes away. A crude work-around would be to just add text (with plt.text) at the top and position it where you want it, again using horizontal alignment. – pasnik Jun 04 '22 at 22:22
  • @pasnik I think `ticks = ax.xaxis.get_majorticklabels()` followed by `ticks[0].set_horizontalalignment("left")` resolved the issue. – Kevin Jun 05 '22 at 10:55
  • Great that there's a way, but annoying that it's inconsistent – pasnik Jun 06 '22 at 16:40

0 Answers0