[Matplotlib-users] possible regression in plt.draw (mpl 1.4.3 -> 1.5.0) when using fig.text using transformations

Thomas Caswell tcaswell at gmail.com
Thu Mar 3 08:54:05 EST 2016


If you want to _really_ force a redraw, you will need to to
`fig.canvas.draw()`.

In https://github.com/matplotlib/matplotlib/pull/5150 we change
`plt.draw()` to use the `canvas.draw_idle` method.  The draw_idle
effectively asks the GUI framework to please re-draw the next time it is
convenient.  The main benefit of this is if you request multiple draw_idle
before giving the GUI a chance to re-paint there will only be one actual
call to `canvas.draw`.

Using `ax.text` is much simpler you should just use that ;)

In general going through screen coordinates in user code is not advised.
In this particular case you are going right back to 'normalized' unit so
you will not have DPI / figure size issues, but in general those will come
up because the Transforms close over many values that can (and do!) change
from user input or as part of the draw process.  In almost all cases, it is
better to pass a transfrom into the artists and let mpl internals sort of
exactly when to evaluate them.

Tom

On Thu, Mar 3, 2016 at 6:31 AM Oliver Willekens <oliver.willekens at gmail.com>
wrote:

> Dear matplotlib users and developers,
>
> I’m using plt.draw() to force the rendering of all artists and then,
> based on their newly calculated positions, place a text label on the figure
> window in figure coordinates.
>
> The goal is to add a text label near the conventional y-axis, at the top,
> right-aligned. Example code that demonstrates the problem:
>
> #!/usr/bin/env python
> # -*- coding: utf-8 -*-
> import numpy as np
> import matplotlib.pyplot as plt
> import matplotlib as mpl
> print(mpl.__version__)
>
> x = np.linspace(0, 50)
> y = 4*np.sin(x) + 5
>
> fig = plt.figure(figsize=(18,9.8))
> ax = fig.add_axes((0.1, 0.1, 0.8, 0.8),
>     frameon=True,
>     aspect='equal',
>     adjustable='box',
>     xlim=(x.min(), x.max()),
>     ylim=(0, 10),
>     xticks=[x.min(), x.max()],
>     yticks=[0, 10],
>     xlabel='dimension (unit)')
> ax.plot(x, y)
> plt.draw()  # force redraw
>
> ylabel_pos = fig.transFigure.inverted().transform_point(ax.transAxes.transform_point((0,1)))
> label1 = fig.text(ylabel_pos[0], ylabel_pos[1], "label1", ha="right", va="bottom")
> plt.savefig('/tmp/test_pre_mpl_v_{}.png'.format(mpl.__version__))
> ylabel_pos = fig.transFigure.inverted().transform_point(ax.transAxes.transform_point((0,1)))
> label2 = fig.text(ylabel_pos[0], ylabel_pos[1], "label2", ha="right", va="bottom")
> plt.savefig('/tmp/test_post_mpl_v_{}.png'.format(mpl.__version__))
>
> The code shows that in mpl 1.4.3 both label1 and label2 end up at the same
> (desired) position. However, mpl 1.5.0 and 1.5.1 (just installed to check)
> show that label1 is at a height of 0.9 in the figure coordinates. After the
> first call to savefig, the figure is rendered with the axes getting a new
> height and width (due to the call to aspect='equal', adjustable='box')
> and so the subsequent call to savefig renders label2 in the correct
> position.
>
> Using ax.text(x=0, y=1, s='label', transform=ax.transAxes, ha="right",
> va="bottom") gets the job done alright (both in 1.4.3, as well as 1.5.0),
> but the call to fig.text using the subsequent transforms should have
> worked, I believe, and so this seems to indicate something has changed in
> the rendering of a rescaled axes using plt.draw.
>
> Kind regards,
> Oliver
>
> P.S. I posted this to the older sourceforge mailing list as well, by
> accident. Hadn’t changed the send-to address yet, even though Thomas
> Caswell had pointed it out to me already in August 2015. My apologies.
>> _______________________________________________
> Matplotlib-users mailing list
> Matplotlib-users at python.org
> https://mail.python.org/mailman/listinfo/matplotlib-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20160303/9693af0a/attachment-0001.html>


More information about the Matplotlib-users mailing list