matplotlib 在多图中的第二个坐标轴上设置副纵轴标签

huangapple go评论99阅读模式
英文:

matplotlib supylabel on second axis of multiplot

问题

I'm not finding it possible to add a second supylabel for a right-hand y-axis of a multiplot.

Can anyone please confirm 1) whether or not it can be done and/or 2) provide guidance on how?

I am trying to achieve this:
matplotlib 在多图中的第二个坐标轴上设置副纵轴标签

Because there are a variable number of subplots (sometimes an odd number, sometimes even) across the broader project, using subplot-level labeling to label the "middle" subplot would be problematic.

I'm presently accomplishing with figure level text. Which looks fine within python, but the right label gets cut-off by savefig. I can only get it to work if I dummy-in null ax-level y-labels " \n".

  1. nrows = len(dftmp.GroupingCol.unique())
  2. ncols = 1
  3. fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=(14,10), constrained_layout=True,
  4. sharex=True)
  5. for e, ep in enumerate(dftmp.GroupingCol.unique(), start=1):
  6. # define a figure axis and plot data
  7. ax = plt.subplot(nrows, ncols, e)
  8. dftmp["ValueCol"].loc[dftmp["GroupingCol"]==ep].plot(ax=ax, kind="bar", color=barcolor_lst)
  9. # horizontal reference line (zero change)
  10. zero_line = plt.axhline(0, color='k', linewidth=0.8)
  11. # y-axis extent limits
  12. ax.set ylim([50*(-1.1), 50*1.1])
  13. # create right-hand y-axis
  14. ax2 = ax.twinx()
  15. # y-axis extent limits
  16. ax2.set ylim([200*(-1), 200])
  17. # null y-label placeholder to accommodate fig-level pseudo-supylabel
  18. ax2.set_ylabel(" \n")
  19. # create supylabel for left-axis
  20. supy_left = fig.supylabel("Left-hand y-axis super label", fontweight="bold")
  21. # use fig-level text as pseudo-supylabel for right-axis
  22. fig.text(x=0.97, y=0.5, s="Right-hand y-axis super label\n\n", size=13, fontweight='bold', rotation=270, ha='center', va='center')
  23. # create super-label for x-axis
  24. supx = fig.supxlabel("Bottom super label", fontweight="bold")

In the absence of the fig.text line, I tried naming a second supylabel as a different object and the code runs, but doesn't produce the label.

  1. supy_right = fig.supylabel("Cumulative net change (m^3)", fontweight="bold", position=(0.9,0.5))
英文:

I'm not finding it possible to add a second supylabel for a right-hand y-axis of a multiplot.

Can anyone please confirm 1) whether or not it can be done and/or 2)provide guidance on how?

I am trying to achieve this:
matplotlib 在多图中的第二个坐标轴上设置副纵轴标签

Because there are a variable number of subplots (sometimes an odd number, sometimes even) across the broader project, using subplot-level labelling to label the "middle" subplot would be problematic.

I'm presently accomplishing with figure level text. Which looks fine within python, but the right label gets cut-off by savefig. I can only get it to work if I dummy-in null ax-level y-labels " \n".

  1. nrows = len(dftmp.GroupingCol.unique())
  2. ncols = 1
  3. fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=(14,10), constrained_layout=True,
  4. sharex=True)
  5. for e, ep in enumerate(dftmp.GroupingCol.unique(), start=1):
  6. # define a figure axis and plot data
  7. ax = plt.subplot(nrows, ncols, e)
  8. dftmp["ValueCol"].loc[dftmp["GroupingCol"]==ep].plot(ax=ax, kind="bar", color=barcolor_lst) #, use_index=False)
  9. # horizontal reference line (zero change)
  10. zero_line = plt.axhline(0, color='k', linewidth=0.8)
  11. # y-axis extent limits
  12. ax.set_ylim([50*(-1.1), 50*1.1])
  13. # create right-hand y-axis
  14. ax2 = ax.twinx()
  15. # y-axis extent limits
  16. ax2.set_ylim([200*(-1), 200])
  17. # null y-label placeholder to accommodate fig-level pseudo-supylabel
  18. ax2.set_ylabel(" \n") # requires space and newline to work
  19. # create supylabel for left-axis
  20. supy_left = fig.supylabel("Left-hand y-axis super label", fontweight="bold") #, pad = 7)#, fontdict=fontdict) #fontweight='bold')
  21. # use fig-level text as pseudo-supylable for right-axis
  22. fig.text(x=0.97, y=0.5, s="Right-hand y-axis super label\n\n", size=13, fontweight='bold', rotation=270, ha='center', va='center')
  23. # create super-label for x-axis
  24. supx = fig.supxlabel("Bottom super label", fontweight="bold")

In the absence of the fig.text line I tried naming a second supylabel as a different object and the code runs, but doesn't produce the label.

  1. supy_right = fig.supylabel("Cumulative net change (m^3)", fontweight="bold", position=(0.9,0.5))

答案1

得分: 1

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(4, 4))

dummy axes 1

ax = fig.add_subplot(1, 1, 1)
ax.set_xticks([])
ax.set_yticks([])
[ax.spines[side].set_visible(False) for side in ('left', 'top', 'right', 'bottom')]
ax.patch.set_visible(False)
ax.set_xlabel('x label', labelpad=30)
ax.set_ylabel('y label left', labelpad=30)

dummy axes 2 for right ylabel

ax = fig add_subplot(1, 1, 1)
ax.set_xticks([])
ax.set_yticks([])
[ax.spines[side].set_visible(False) for side in ('left', 'top', 'right', 'bottom')]
ax.patch.set_visible(False)
ax.yaxis.set_label_position('right')
ax.set_ylabel('y label right', labelpad=30)

actual data axes

num_rows = 4

for i in range(num_rows):
ax = fig.add_subplot(num_rows, 1, i + 1)
...

fig.tight_layout()

英文:

I have found the suplabels to be a little unreliable in many cases, so I resort to low-level tricks in cases like these:

  1. import matplotlib.pyplot as plt
  2. fig = plt.figure(figsize=(4, 4))
  3. # dummy axes 1
  4. ax = fig.add_subplot(1, 1, 1)
  5. ax.set_xticks([])
  6. ax.set_yticks([])
  7. [ax.spines[side].set_visible(False) for side in ('left', 'top', 'right', 'bottom')]
  8. ax.patch.set_visible(False)
  9. ax.set_xlabel('x label', labelpad=30)
  10. ax.set_ylabel('y label left', labelpad=30)
  11. # dummy axes 2 for right ylabel
  12. ax = fig.add_subplot(1, 1, 1)
  13. ax.set_xticks([])
  14. ax.set_yticks([])
  15. [ax.spines[side].set_visible(False) for side in ('left', 'top', 'right', 'bottom')]
  16. ax.patch.set_visible(False)
  17. ax.yaxis.set_label_position('right')
  18. ax.set_ylabel('y label right', labelpad=30)
  19. # actual data axes
  20. num_rows = 4
  21. for i in range(num_rows):
  22. ax = fig.add_subplot(num_rows, 1, i + 1)
  23. ...
  24. fig.tight_layout()

matplotlib 在多图中的第二个坐标轴上设置副纵轴标签

You need to adjust the labelpad values according to your liking. The rest can be taken care of by fig.tight_layout() (you might need to specify the rect though).


EDIT: having re-read your question, have you tried increasing the pad_inches value when calling savefig()?

huangapple
  • 本文由 发表于 2023年2月6日 13:01:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75357468.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定