Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Get proper renderer width and height in FigureImage #9204

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

Merged
merged 9 commits into from
Sep 24, 2017

Conversation

jklymak
Copy link
Member

@jklymak jklymak commented Sep 19, 2017

Possible fix to #9203. Works with their example.

Issue was that renderer.width would return 1.0, but we really needed width, height = renderer.get_canvas_width_height().

Their test was:

import matplotlib.pyplot as plt
import numpy as np
data = np.arange(100*100).reshape(100, 100).astype(float)
plt.imsave("test.pdf", data, origin="lower", format="pdf") #same behavior also with eps instead of pdf

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code is PEP 8 compliant

@dstansby
Copy link
Member

This definitely needs a test adding! Could you add your example in the bug report to lib/matplotlib/tests/test_image.py?

@dstansby dstansby added this to the 2.1 (next point release) milestone Sep 19, 2017
@dstansby dstansby added the Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. label Sep 19, 2017
@jklymak
Copy link
Member Author

jklymak commented Sep 19, 2017

Changig to WIP - see below, but width, height = renderer.get_canvas_width_height() doesn't seem to know about dpi in fig = plt.figure(figsize=(2,2), dpi=100)...

@dstansby

For the tests, there is already the test below, but as you can see it is only set to check png.

@image_comparison(baseline_images=['figimage-0', 'figimage-1'], extensions=['png'])
def test_figimage():
    'test the figimage method'

    for suppressComposite in False, True:
        fig = plt.figure(figsize=(2,2), dpi=100)
        fig.suppressComposite = suppressComposite
        x,y = np.ix_(np.arange(100.0)/100.0, np.arange(100.0)/100.0)
        z = np.sin(x**2 + y**2 - x*y)
        c = np.sin(20*x**2 + 50*y**2)
        img = z + c/5

        fig.figimage(img, xo=0, yo=0, origin='lower')
        fig.figimage(img[::-1,:], xo=0, yo=100, origin='lower')
        fig.figimage(img[:,::-1], xo=100, yo=0, origin='lower')
        fig.figimage(img[::-1,::-1], xo=100, yo=100, origin='lower')

Unfortunately this turns up a continued error, and I'm not quite sure how to get around it...

If I modify the above to run from the command line:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
for suppressComposite in False, True:
    fig = plt.figure(figsize=(2,2), dpi=100)
    fig.suppressComposite = suppressComposite
    x,y = np.ix_(np.arange(100.0)/100.0, np.arange(100.0)/100.0)
    z = np.sin(x**2 + y**2 - x*y)
    c = np.sin(20*x**2 + 50*y**2)
    img = z + c/5

    fig.figimage(img, xo=0, yo=0, origin='lower')
    fig.figimage(img[::-1,:], xo=0, yo=100, origin='lower')
    fig.figimage(img[:,::-1], xo=100, yo=0, origin='lower')
    fig.figimage(img[::-1,::-1], xo=100, yo=100, origin='lower')

    if suppressComposite:
        fig.savefig('Boo.pdf')
        fig.savefig('Boo.png')
    else:
        fig.savefig('Boo2.pdf')
        fig.savefig('Boo2.png')

For pdf rendering get_canvas_width_height() is returning 144, 144 instead of 200, 200 for the above so it is ignoring the figure specified dpi and using a default value of 72. If I save as png, it assumes that dpi=300 and returns 600, 600.

So, somehow the backends are getting the figsize, but they are not getting the dpi from the fig = plt.figure(figsize=(2,2), dpi=100) command, at least as reported by width, height = renderer.get_canvas_width_height()

@jklymak jklymak changed the title get proper renderer width and height in FigureImage WIP: get proper renderer width and height in FigureImage Sep 19, 2017
@jklymak
Copy link
Member Author

jklymak commented Sep 19, 2017

OK, so the matplotlib.backends.backend_mixed.MixedModeRenderer, which gets used when making the pdf and the matplotlib.backends.backend_agg.RendererAgg return very different values of width and height, and that is the problem.

For renderer.width, RenderAgg returns fig.width * fig.dpi and MixedModeRenderer simply returns fig.width. So, this PR is almost certainly wrong to use the canvas method, but the two renderers should probably be made compatible...

@jklymak jklymak closed this Sep 19, 2017
@jklymak jklymak reopened this Sep 19, 2017
@jklymak jklymak changed the title WIP: get proper renderer width and height in FigureImage Get proper renderer width and height in FigureImage Sep 20, 2017
@jklymak
Copy link
Member Author

jklymak commented Sep 20, 2017

@dstansby the test is the existing test_image.py:test_figimage with the svg and pdf filetypes added...

@jklymak
Copy link
Member Author

jklymak commented Sep 20, 2017

Todo: remove or fix the svg test...

'test the figimage method'

for suppressComposite in False, True:
for suppressComposite in [False]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit concerned that we are losing testing the supressComposite=True code path.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, never mind, I should have read the next part of diff 🐑

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe I should clean this a bit. The for-loop worked when the test only did png, but never got to the second pdf for some reason. This (ahem) "fixed" the problem.

'test the figimage method'

for suppressComposite in False, True:
for suppressComposite in [False]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, never mind, I should have read the next part of diff 🐑

Copy link
Member

@dstansby dstansby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 👍

@tacaswell tacaswell merged commit 5f63dd4 into matplotlib:master Sep 24, 2017
tacaswell added a commit that referenced this pull request Sep 24, 2017
FIX: Get proper renderer width and height in FigureImage
@tacaswell
Copy link
Member

Thanks! backported to v2.1.x as 052b52b

@jklymak jklymak deleted the fiximage branch March 5, 2019 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants