-
Notifications
You must be signed in to change notification settings - Fork 26
Revisiting figure size API #158
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
Comments
Hi - thanks for reaching out! Tueplots' figure sizes support a |
It closes some use cases. Thank you! However, it does not cover padding issues. Specifically, it is still unclear how one can make the following layout without manual adjustments.
|
Thanks for following up. Yes, padding is a bit tedious in this context. One relatively simple fix that might work is to adjust rel_width up or down according to the desired padding. How critical is it to make all subplots in separate scripts? I create plots with layouts like the one you're providing relatively frequently. I typically combine a global figure size (via tueplots) with |
Honestly, it is quite rare case (one figure per 10 pages paper). The need to split figure rendering part by part stems from the use of addition (vector) graphics that gives instructive image or illustrates entire experiment setup. In this case, it much simpler to collate figure manually. Personally, I use a simple routine that adjust figure size in |
Oh, I haven't thought about that. This use case seems worth thinking about, indeed. Thanks for raising this :) I looked some more into it. Bad news: I struggled a bit with understanding your code example, but I don't know much HTML/CSS, so that's likely the reason. Good news: One can load SVGs into matplotlib figures and use Tueplots to configure the size of that figure. I drafted a tutorial on how to make this work. Could you maybe have a look at this draft to see whether it solves your problem? Thanks! |
Sorry to bother you again, @daskol... Does the thumbs-up reaction to the previous message mean you like the solution, or does it mean something else? 😅 Thanks for your feedback; it's much appreciated 😊 |
Sorry for the delay.
No problem. It was just a sign that I have read your reply but haven't figured out the workaround yet. Sorry. 😅
Embedding any graphics and in particular SVG graphics as rasterized PNG is indeed a workaround. However, benefits of vector images (selectable text, infinite zoom in, small memory footprint) are lost in this case. Specifically, Matplotlib rasterizes a raster image once again in order to fit a bounding box of a target area. Another issue is that rendering figures with rasterized SVG graphics to vector graphics produces a vector image with the rasterized original vector graphics (i.e. everything can be vector but collation with Matplotlib inevitably turns the original vector graphics into raster one). Thus I would prefer manual collation to collation with Matplotlib.
I fixed the code in the initial comment and prepared a usage example. Usage exampleimport matplotlib.pyplot as plt
def annotate(ax: plt.Axes, text: str):
ax.annotate(text, (0.5, 0.5), transform=ax.transAxes,
ha='center', va='center', fontsize=32, color='darkgrey')
# Vector graphics spans two rows (A).
layout = [['A', 'B'],
['A', 'C']]
# Render all subfigures as a single combined figure.
fig_size = figsize(size=(1, 1), grid=(1, 1)) # Use defaults.
fig_size = fig_size[::-1] # TODO: Swap width and height.
assert fig_size == (5.5, 3.3991869382292417)
fig, axs = plt.subplot_mosaic(layout, figsize=fig_size, layout='constrained')
annotate(axs['A'], 'A')
annotate(axs['B'], 'B')
annotate(axs['C'], 'C')
fig.savefig('full.png', dpi=144)
plt.close(fig)
# Each plot (B and C) span a single column and single row.
fig_size = figsize(size=(1, 1), grid=(2, 2))
fig_size = fig_size[::-1] # TODO: Swap width and height.
assert fig_size == (2.75, 1.6995934691146208)
for ch in 'BC':
fig, ax = plt.subplots(figsize=fig_size, layout='constrained')
annotate(ax, ch)
fig.savefig(f'{ch}.png', dpi=144)
plt.close(fig) If one verifies the real sizes of the resulting images, then it turns out that the size of $ file *.png
B.png: PNG image data, 396 x 244, 8-bit/color RGBA, non-interlaced
C.png: PNG image data, 396 x 244, 8-bit/color RGBA, non-interlaced
full.png: PNG image data, 792 x 489, 8-bit/color RGBA, non-interlaced |
Thanks for elaborating! Just a heads-up that I've seen your message but haven't had a chance to dig into it yet. I'll try to take a look next week! 😊 |
Rationale
Currently,
tueplots
provides incomplete and inconsistent API for figure size specification. The issue is thattueplots
assumes that user always request the size of entire figure with all subfigures but it is highly inconvenient in case of rendering subfigures separately and manual collation on page later.Here is a specific example. ICLR-styled document has a single column of width 5.5. One needs two plots side-by-sides presented as a single one figure. Thus, manual manipulation of figure dimensions is required.
Proposal
I suggest to explicit specification of page grid and figure size in grid coordinates. This is similar to how grid system works in HTML/CSS. It is simple, clear, and flexible but slightly more verbose. However, it enables precise figure size specification for an arbitrary subfigure composition on a page. Optionally,
figsize()
routine can obtain arguments for width and height of an entire figure to avoid automatic guessing.Example and tests
What are your thoughts on this matter?
The text was updated successfully, but these errors were encountered: