-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Svg rasterize resolution fix #1185
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
Changes from 1 commit
309c93c
cb1aa37
868f411
98ab64e
7eacb85
f56a455
c610462
dc0a819
d6f4931
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -244,10 +244,11 @@ class RendererSVG(RendererBase): | |
FONT_SCALE = 100.0 | ||
fontd = maxdict(50) | ||
|
||
def __init__(self, width, height, svgwriter, basename=None): | ||
def __init__(self, width, height, image_dpi, svgwriter, basename=None): | ||
self.width = width | ||
self.height = height | ||
self.writer = XMLWriter(svgwriter) | ||
self.image_dpi = image_dpi # the actual dpi we want to rasterize stuff with | ||
|
||
self._groupd = {} | ||
if not rcParams['svg.image_inline']: | ||
|
@@ -733,6 +734,11 @@ def draw_gouraud_triangles(self, gc, triangles_array, colors_array, | |
def option_scale_image(self): | ||
return True | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: Only need a single new line between methods. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
|
||
def get_image_magnification(self): | ||
return self.image_dpi/72.0 | ||
|
||
|
||
def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mwelter - I don't know how much you've invested in checking out the details of this signature but it is worth noting that all backends have it, except for the I promise that PR wont take 8 months to merge 😉 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nah, sorry. I happly contribute what i have done. But at the moment i am not willing to look into more stuff. |
||
attrib = {} | ||
clipid = self._get_clip(gc) | ||
|
@@ -755,6 +761,17 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None): | |
im.resize(numcols, numrows) | ||
|
||
h,w = im.get_size_out() | ||
|
||
if dx is None: | ||
w = 72.0*w/self.image_dpi | ||
else: | ||
w = dx | ||
|
||
if dy is None: | ||
h = 72.0*h/self.image_dpi | ||
else: | ||
h = dy | ||
|
||
oid = getattr(im, '_gid', None) | ||
url = getattr(im, '_url', None) | ||
if url is not None: | ||
|
@@ -1113,25 +1130,17 @@ def print_svgz(self, filename, *args, **kwargs): | |
|
||
def _print_svg(self, filename, svgwriter, fh_to_close=None, **kwargs): | ||
try: | ||
image_dpi = kwargs.pop("dpi", 72) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the difference between this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is in a different class. From here image_dpi gets passed to the backends constructor. |
||
self.figure.set_dpi(72.0) | ||
width, height = self.figure.get_size_inches() | ||
w, h = width*72, height*72 | ||
|
||
if rcParams['svg.image_noscale']: | ||
renderer = RendererSVG(w, h, svgwriter, filename) | ||
renderer = RendererSVG(w, h, image_dpi, svgwriter, filename) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. API change needs to be fixed here |
||
else: | ||
# setting mixed renderer dpi other than 72 results in | ||
# incorrect size of the rasterized image. It seems that the | ||
# svg internally uses fixed dpi of 72 and seems to cause | ||
# the problem. I hope someone who knows the svg backends | ||
# take a look at this problem. Meanwhile, the dpi | ||
# parameter is ignored and image_dpi is fixed at 72. - JJL | ||
|
||
#image_dpi = kwargs.pop("dpi", 72) | ||
image_dpi = 72 | ||
_bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) | ||
renderer = MixedModeRenderer(self.figure, | ||
width, height, image_dpi, RendererSVG(w, h, svgwriter, filename), | ||
width, height, image_dpi, RendererSVG(w, h, image_dpi, svgwriter, filename), | ||
bbox_inches_restore=_bbox_inches_restore) | ||
|
||
self.figure.draw(renderer) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -160,6 +160,33 @@ def test_no_interpolation_origin(): | |
ax = fig.add_subplot(212) | ||
ax.imshow(np.arange(100).reshape((2, 50)), interpolation='none') | ||
|
||
|
||
@image_comparison(baseline_images=['rasterize_10dpi'], extensions=['pdf','svg'], tol=1.5e-3, remove_text=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line width is probably longer than 80 chars. Please wrap the line. |
||
def test_rasterize_dpi(): | ||
# This test should check rasterized rendering with high output resolution. | ||
# It plots a rasterized line and a normal image with implot. So it will catch | ||
# when images end up in the wrong place in case of non-standard dpi setting. | ||
# Instead of high-res rasterization i use low-res. Therefor the fact that the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo. Therefor -> Therefore. (if your interested, therefor is a proper word, but would not be correct in this case: http://walkinthewords.blogspot.co.uk/2009/04/therefor-vs-therefore.html) |
||
# resolution is non-standard is is easily checked by image_comparison. | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
img = np.asarray([[1, 2], [3, 4]]) | ||
|
||
fig, axes = plt.subplots(1, 3, figsize = (3, 1)) | ||
|
||
axes[0].imshow(img) | ||
|
||
axes[1].plot([0,1],[0,1], linewidth=20., rasterized=True) | ||
axes[1].set(xlim = (0,1), ylim = (-1, 2)) | ||
|
||
axes[2].plot([0,1],[0,1], linewidth=20.) | ||
axes[2].set(xlim = (0,1), ylim = (-1, 2)) | ||
|
||
rcParams['savefig.dpi'] = 10 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless I am mistaken, this is going to have a side effect on subsequent tests. Perhaps the image comparison decorator should accept a dictionary of overwriting rc params... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oddly enough it actually doesn't show any side effects. It would surely show in the images. Some good old debugging through print statements also shows that apparently changes to rcParams don't carry over to the next test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p.s. we already have @image_comparison(baseline_images=['interp_nearest_vs_none'],
extensions=['pdf', 'svg'], remove_text=True)
def test_interp_nearest_vs_none():
'Test the effect of "nearest" and "none" interpolation'
# Setting dpi to something really small makes the difference very
# visible. This works fine with pdf, since the dpi setting doesn't
# affect anything but images, but the agg output becomes unusably
# small.
rcParams['savefig.dpi'] = 3
X = np.array([[[218, 165, 32], [122, 103, 238]],
[[127, 255, 0], [255, 99, 71]]], dtype=np.uint8)
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax1.imshow(X, interpolation='none')
ax1.set_title('interpolation none')
ax2 = fig.add_subplot(122)
ax2.imshow(X, interpolation='nearest')
ax2.set_title('interpolation nearest') So, hopefully everything is alright. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @mwelter - I was mistaken 😄 |
||
|
||
|
||
|
||
if __name__=='__main__': | ||
import nose | ||
nose.runmodule(argv=['-s','--with-doctest'], exit=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed this. This changes the API of this class. Backends are used by other projects and are not considered to be internal-only, IMO. It would be better to put image_dpi at the end of the call signature with a None (or whatever default value that makes sense).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This API change still needs to be addressed.