Skip to content

Allow 'ultraplot'-style figure sizing options #1422

@tgbrooks

Description

@tgbrooks

A frequent source of annoyance when using matplotlib or ggplot is the need to specify the dimensions of the entire figure. After that, the figure is subdivided into axes, labels, etc. This makes it difficult to control the appearance of the figure and often results in guess-and-check tweaking of the figure size, which is doable for static figures but practically impossible to get right if figures are dynamically generated under a fairly wide range of conditions.

The library ultraplot builds on top of matplotlib and notably it enables users to specify figure sizing in a more natural way. There are two main options (to my understanding):

  1. Specify the width of the figure and the aspect ratios of the subplots. The figure height is then grown to accommodate the figure elements.
  2. Specify the size of the subplots. The figure height and width is then grown to accommodate the figure elements.

The ultraplot documentation describes this in a little more detail.

There are many cases where this is useful. For example, if I use facet_grid with n rows, then I typically want to describe the shape of a row and have the figure be as tall as needed to accommodate all n rows. In matplotlib or ggplot, you have to change height manually to do this and often I end up trying to guesstimate some formula like height = 100 + 200*n. Another example is a heatmap where you want to set the size of individual cells which is easy to do by setting the subplot widths and heights but is very difficult to do by setting the figure width and height because the space needed for row/column labels and colorbars isn't known in advance. Setting the aspect ratio of the heatmap typically results in whitespace surrounding the plot, such as this:

Image
import numpy as np
import lets_plot as lp
import polars as lp
i,j = np.meshgrid(np.arange(10), np.arange(100))
data = pl.DataFrame({
    'x': i.flatten(),
    'y': j.flatten(),
    'z': np.random.random(size=i.flatten().shape[0]),
})
p1 = (lp.ggplot(data, lp.aes(x='x', y='y',fill='z'))
      + lp.geom_tile()
      + lp.coord_fixed(ratio=1)
     )
lp.ggsave(p1, "out.png", w=5, h = 10, unit='in', dpi=70)# what should I pick for h so that I fill the desired width?

As far as I know, LetsPlot does not have support for this. Adopting the figure size specification options of ultraplot would significantly address this difficulty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions