High effort, creation of logic to create “high quality aesthetic graphs” viable? Comments?

I’ve been working on a project using Matplotlib to “automatically” produce “publication” quality graphs for simple classes of data, such as line plots.

The goal is to produce an appearance that exceeds what can be achieved by just theme changes. It looks better than what can easily be achieved by Matplotlib or common packages (bokeh, Seaborn, etc.).

To do this, I’ve been getting into the weeds. I have questions about design decisions from a development perspective:

  1. Does this project and the work involved sound sane, or will I be fighting Matplotlib’s design the whole way?

  2. Are there others who have tried such a thing before?

Here’s one example to illustrate:

I’ve been rolling my own “custom X-axis”.

This is because I want to expand the plot beyond what is normally plotted for aesthetic reasons. I haven’t found a reliable, well documented way to do this in the documentation.

So to expand my plot, I add data to both ends.

That is, say, I want to plot 100 points of data from 1 to 100. Instead of a plot from 0,1,2,3,…99, 100. I add in an extra 10 points on either end, so it’s -10,-9,8,…108,109,100.

I then need to roll custom labels for the resulting custom x axis.

There’s more—for example, I’m rolling my own logic for automatic labelling and processing of data related information (detecting if the inputted data is at the minute, day, year level and creating aesthetic labels).

All this work has a nice “bare metal” feel, but I’m also worried this is the path to insanity.

Comments? Has anyone done this before?

Everything you have described so far matplotlib already does, to one extent or another. For instance your extra space on the x axis are called “margins” and we have a whole date handling module. Before rolling your own make sure you are familiar with all the existing features!

Hi Jody,

For instance your extra space on the x axis are called “margins” and we have a whole date handling module.

I think you are referring to this:

https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/axes_margins.html#sphx-glr-gallery-subplots-axes-and-figures-axes-margins-py

  1. The margin parameters in the feature seem to be at the axis level, so changing this amounts to a uniform “zooming in” or “zooming out”, instead of adding a buffer left or right. This is probably inadequate for the level of control / aesthetics in the premise of the original post. See:
    python - Matplotlib: Set different margins for left and right side - Stack Overflow
  1. Use of the indicated margins feature produces highly unacceptable artifacts in the particular use of at least plot type: fill_between. Here, when using facecolors and edgecolors that are different, the end of the fill_between plot has a large glaring downward line at the end of the plot, where the edge line dives vertically to meet the x-axis. Using margins to zoom out reveals this artifact. Note that this artifact is not merely aesthetical but suggests the data has gone to zero. This is worked around by adding the plot as described. There may be other such plots with similar issues.

we have a whole date handling module

  1. A major use case for hand rolled x axis is data where weekend or holiday data is missing. This is common in financial or business data. Matplotlib’s own documentation literally recommends users roll their own x-axis, that is, specifying ticks and labels. If a user is doing this, it’s unclear if using a higher-level date handling module is wise or easier then just continuing down this handrolled path.

Discussion (with link to actual Matplotlib documentation): How to skip empty dates (weekends) in a financial Matplotlib Python graph? - Stack Overflow

  1. One component of the logic I am describing is automatically creating formats, scaling with data from the minute level to the century level. There are some pretty arcane rules involved to make this look great. A few steps before this is the principle that is that you do not need to show “seconds” data if you’re plotting at the “century level”, etc. I cannot find any logic that has Matplotlib automatically determine this. Instead, stack exchange has users specifying date formats to avoid unnecessary seconds:

<ERROR: cannot put in links to stack exchange or matplotlib > - CH

  1. Using this discourse forum, I am experiencing large errors and complaints in putting up my links (to matplotlib.org and stack exchange).

  2. My content is being flagged for review, presumably automatically.

The above issues are scrambling my input and, well, trashing elaborate, high effort explanations.

This forum experience seems unworkable for continuing this discussion.

It was flagging you for some reason, but it has been restored now.

1 Like

Inadequate is in the eye of the beholder - the way we provide flexibility is by giving the user access to lower level APIs. But the basic helpers are typically basic.

A major use case for hand rolled x axis is data where weekend or holiday data is missing.

Agree about this - but the reason that needs a special axis is it actually requires a different scale so that the weekends are collapsed to zero width. The example is actually a hack around this, but someone who needs this sort of plotting should totally write a wrapper.

One component of the logic I am describing is automatically creating formats, scaling with data from the minute level to the century level.

Did you see ConciseDate Formatter? Formatting date ticks using ConciseDateFormatter — Matplotlib 3.3.4 documentation It is an attempt to do what you are suggesting (though not with financial time series)

Did you see ConciseDate Formatter? Formatting date ticks using ConciseDateFormatter — Matplotlib 3.3.4 documentation It is an attempt to do what you are suggesting (though not with financial time series)

This is helpful and the formatting is very much what I want to achieve.

Inadequate is in the eye of the beholder - the way we provide flexibility is by giving the user access to lower level APIs. But the basic helpers are typically basic.

These responses are helpful and the existence of a detailed special feature like ConciseDateFormatter suggests the premise of my project is probably acceptable.

I guess my personal experience of the “signposting” to these corners of Matplotlib is spotty, especially when I start with stack exchange.

Thanks Jody.