Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Known Issue: Left-flushing of annotations relies on the monospace font #62

Open
sjiang40 opened this issue Mar 14, 2023 · 3 comments
Open
Labels
Help Wanted Help wanted/needed

Comments

@sjiang40
Copy link

I would like to use different fonts (e.g. Helvetica, Arial) to match journal font requirements for publication-ready figures.

A potential fix could be to use matplotlib.pyplot.table to render the table text to allow left-align with any font.

@LSYS
Copy link
Owner

LSYS commented Mar 21, 2023

Hey sjiang40, thanks so much for pointing me to matplotlib.pyplot.table. I was not aware of this. Seems like a potential solution to aligning the y-labels. Will investigate this for a future release. @sjiang40 Let me know if it's something you want to work on.

@sjiang40
Copy link
Author

sjiang40 commented Mar 29, 2023

@LSYS I would love to help but I will be on rotations in the hospital for the foreseeable future and I will have to spend my free time working on other research. Assuming you get to this before I get a chance to, I suspect matplotlib.pyplot.table will be a viable solution for this.

Alternatively, if matplotlib.pyplot.table ends up being too much of a code refactor, I recently wrote some code to add multiple Text() objects in series as if it were a single object. The purpose was to add a bolded subfigure label with normal subfigure title without using LaTeX (e.g. "A) Subfigure title"). I think the core algorithm can be adapted to align columns in a table independent of the font. The steps would essentially be:

  1. Place all text on the axis
  2. Draw the plot
  3. Identify the maximum width Text() object in each column
  4. Horizontally shift each column accordingly

Here's some example code from my use case (note: this example is not robust and assumes va= 'center' and loc='center'):

import matplotlib.pyplot as plt

# Assign variables
fig, ax = plt.subplots(1, 1)
renderer = fig.canvas.get_renderer()
transform = ax.transAxes

# Draw center line reference
ax.vlines(.5, ymin=0, ymax=1, transform=transform)

# Place title and label on ax in arbitrary location and draw objects
title_obj = ax.set_title('Subfigure title', va='center', loc='center')
label_obj = ax.text(.5, .5, 'A) ', va='center', fontweight='bold', transform=transform)
plt.draw()

# Get title coordinates, width, and position
bb = title_obj.get_window_extent(renderer=renderer)
bb_coords = bb.transformed(transform.inverted()).get_points()
title_x1, title_x2, title_y1, title_y2 = bb_coords[0][0], bb_coords[1][0], bb_coords[0][1], bb_coords[1][1]
title_w = title_x2 - title_x1
x_pos = title_obj.get_position()[0]
y_pos = (title_y1 + title_y2) / 2

# Get label coordinates and width
bb = label_obj.get_window_extent(renderer=renderer)
bb_coords = bb.transformed(transform.inverted()).get_points()
label_x1, label_x2, label_y1, label_y2 = bb_coords[0][0], bb_coords[1][0], bb_coords[0][1], bb_coords[1][1]
label_w = label_x2 - label_x1

# Define shift offsets
title_offset = label_w / 2
label_offset = -(title_w + label_w) / 2

# Shift title and label horizontally
title_obj.set_position((x_pos + title_offset, y_pos))
label_obj.set_position((x_pos + label_offset, y_pos))

fig.set_facecolor('w')

This code creates this image:
image

@CongWang141
Copy link

would be good to see the text to allow left-align with any font.

@LSYS LSYS added the Help Wanted Help wanted/needed label Aug 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted Help wanted/needed
Projects
None yet
Development

No branches or pull requests

3 participants