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
Update various low resolution graphics for retina displays #2234
Comments
Another thing to note: Safari apparently smooths out low resolution graphics (i.e., the toolbar buttons) and Chrome does not. |
The default resolution of plots is also the easiest to deal with, since it's just matplotlib rcParams, and 2x values are completely inappropriate for everyone else. So I don't think that one is going to change for at least the years it takes for pixel-doubled displays to become relatively common. I expect a Pull Request with 2x assets :) |
Well I imagine that retina displays will be much less than relatively common before the low res plots annoy enough people to get you guys to change it :) I know almost nothing about the code, so I could be wrong here, but I think for the notebook and qtconsole you may need to update something from upstream, if it exists (or in the case of qt, perhaps just wait for an upstream update the supports retina rendering). But again, this is just from a cursory glance at the code, so I could be wrong. The favicon obviously you have complete control over. |
But that's the issue - people with exotic environments need to use non-default config, and that config is trivial right now. Until that becomes standard, it makes no sense to change the defaults. |
I wonder if it would be possible to change it dynamically. Is it possible to determine if a monitor is using 2x assets with javascript? Is the issue that rendering plots with double resolution would be computationally expensive? |
Mostly just a big waste of data. If you want bigger figures, set the figure size to be bigger. One line of config, or one call at runtime. It makes no sense to change defaults to serve a tiny minority to the detriment of everyone else. |
Except for IPython notebook , we depend on jQuery for all that. (maybe they'll switch to a custom font for icon like github does...)
I can't make much higher resolution than a SVG..we'll have to wait for Qt Update.
You are not up to date with your stable version of chrome, [it's still hidden in the page](http://chrome.blogspot.fr/2012/07/new-senses-for-web.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+blogspot/Egta+(Google+Chrome+Blog) ...
If you want to make a PR that fixes some of that... Have fun with your hi-res screen. |
Quite a few of the icons are already in unicode.
Ah. I stopped using the stable version and started using Canary every since I got my new Mac, because I couldn't stand the low res graphics (or the alternative, which is using Safari). And anyway, you still need Canary for the high-res pdf viewer.
The largest notebook icon that I see (in docs/resources/) appears to only be 512 x 512.
Yes, it's pretty awesome, except you notice every low-res graphic on everything (hence my opening this issue). So I guess the only thing that can actually be done here is the favicon. |
I have been unable to figure out how to fix this through config. From web search, I found someone saying that the inline PNG display is hard-coded at 72 dpi to match the qtconsole settings here, and I've found old ipython code that confirms this. However, I can't find current code that would make this true. Please let me know how I can help improve this area. P.S. If anyone has any knowledge of why qtconsole is limited to 72dpi, I'd love to hear it! It looks like crap... |
DPI is just matplotlib config: matplotlib.rcParams['savefig.dpi'] = 144 The inline backend sets some of these values at load time (including DPI), since the matplotlib defaults don't work well in the notebook/qtconsole. You can change these overrides to whatever you want in your config files, e.g.: c.InlineBackend.rc = {
'savefig.dpi' : 144, # 2x
'figure.facecolor' : 'white',
} or change the matplotlib rc directly at any time.
I don't know that it is limited. This DPI number is totally specific to matplotlib figures, and if I recall it was chosen so that switching between SVG/PNG doesn't change the size of figures in the QtConsole (the notebook didn't even exist when this code was written!) If Qt supports 2x rendering, then by all means, proceed with pull requests. |
PNGs do have a DPI field in their header, but I think browsers simply ignore it (almost everything does). It's also possible that matplotlib doesn't even write this header, given how rarely viewers actually pay any attention. To display a 2x PNG, you can send it as HTML instead of raw PNG data. Here's a notebook that hopefully demonstrates how to display 2x figs with IPython. Can you let me know if that looks right? |
Looks good to me. |
Thanks, the 2x figures actually look sharper? I don't want to deal with |
Yes. There's a noticeable difference between the first plot and the later ones. They appear the same size (except for the one that is supposed to be bigger). |
Actually, the first one is a little smaller, but that is the case even on my regular lowdpi external display. |
This lets custom display functions (e.g. HTML) be used without any extra changes (see ipython#2234). possible downsides: * The previous code guarantees that only one format is published. If multiple figure formatters are registered, display will send them all. * If people for some reason disable the type-printers, then they will display the automatic figure display. Neither of these cases can come up unless people are messing with the formatters, and I think the first is actually an improvement.
#2271 should make the post_execute workaround unnecessary. |
That's simply because the actual size matplotlib puts out is not, in fact, strictly dpi * figsize. But it's close enough. If the matplotlib math can be more precisely reproduced (or just inspect the PNG header), then it should match. If there's better CSS for 2x graphics than the most primitive thing I just tossed together, then this can obviously be improved. But the important illustration here is that you can, yourself, enable 2x graphics with no changes to IPython. A more concise version of the code here can just go in a script in your profile startup dir. And ultimately, we can support InlineBackend.figure_format = 'png2x'. |
use display instead of send_figure in inline backend hooks This lets custom display functions (e.g. HTML) be used without any extra changes (see #2234). possible downsides: * The previous code guarantees that only one format is published. If multiple figure formatters are registered, display will send them all. * If people for some reason disable the type-printers, then they will display the automatic figure display. **Backwards-incompatible change** Note that `IPython.zmq.pylab.backend_inline.send_figure` has been removed, as `display()` can do the same job and we avoid an unnecessary special-case code path.
This lets custom display functions (e.g. HTML) be used without any extra changes (see ipython#2234). possible downsides: * The previous code guarantees that only one format is published. If multiple figure formatters are registered, display will send them all. * If people for some reason disable the type-printers, then they will display the automatic figure display. Neither of these cases can come up unless people are messing with the formatters, and I think the first is actually an improvement.
I'm willing to add png2x. I need it too. I will make a PR soon. |
The right way to do this is to add support for image shape information in metadata, as a part of IPEP 13. I've been using this extension to get 2x images in the meantime, but it's definitely the wrong way to do it for real. |
I was going to do exactly what you did in the extension. Guess it's a bad idea then. |
The fix might be as easy as having this display respect the dpi. |
I can also confirm that savefig indeed put DPI in the header. It seems that is img tag just doesn't respect it. Is there any reason the width and height are fixed to that number? |
I think it's an artifact of being able to resize images from the corner. Le jeudi 11 avril 2013, Piti Ongmongkolkul a écrit :
|
Yes it definitely is that dblclick_to_reset_size (around line 432 in outputarea.js. But
var dpr = 1;
console.debug(['aha', img, dpr])
if(window.devicePixelRatio !== undefined) dpr = window.devicePixelRatio; But I couldn't find the way to get image dpi.If I could do this then problem is solved. |
However this will make the default image looks tiny(but sharp) too |
Hmm I'm thinking about this I think the right way is actually the other way around. Instead of having the ipython kernel send the metadata, it should be the browser sending metadata along with the code saying that hey I want hires image. browser --> (code, hires=True) --> kernel --> (hires image) --> browser then browser knows that itself is a hires one and then display with appropriate scaling |
No, because when sharing the notebook or converting it, or having multiple Le samedi 13 avril 2013, Piti Ongmongkolkul a écrit :
|
it is a totally generic use case to specify the size of an image when you display it - 2x graphics is just a simple subset of that. We need to support that use case, so we might as well implement the 2x figures in the same way. |
OK. I'm trying to implement it with metadata but it looks like this will require some change to core API. So I want to consult you first:
What do you think? |
As I proposed in the IPEP I linked above a few times, I think that formatters should be able to either return raw data (as now) or a tuple of length 2 of the form |
what if the raw data is tuple of length 2? |
nvm raw data has to be a dict. I'll have a PR soon. |
Actually that was a valid question: what if raw data returned from formatter is a tuple of length 2? |
There are no display formats for which that is valid. |
To perfectly eliminate any ambiguity, we could always define a particular namedtuple, but the display spec, as it is defined today, there are exactly two display data types: text and bytes. -MinRK On Apr 14, 2013, at 2:14, Min RK benjaminrk@gmail.com wrote:
|
@piti118 are you still working on this? It was next on my todo list, so I can probably get it done fairly quickly. Or I can just do the 'add metadata support' to the display formatters step from my IPEP, which is the more sensitive and pervasive part, and then leave the task of using that logic to get 2x matplotlib figures to you. |
I think it's better to leave the core part to you (I do have partial implementation which I could get it done when i'm free.). I like the plan your propose I can do DPR part. |
Sounds good - I'll have a PR for the metadata stuff this afternoon, and you can base the matplotlib work on that. I know it can be uncomfortable to work on the bits deep inside IPython. |
closed by #3381. |
Images still look bad in the qtconsole. Take for example from sympy import init_session
init_session()
sqrt(x) in the development version of SymPy (make sure you have LaTeX installed). I increased the resolution, but that just made the image bigger :( |
It's the same in the notebook too, actually, but at least the browser antialiases it. Probably this is SymPy's fault, because we probably don't specify a bound for the picture, so it just shows it at the normal resolution. How do you specify a bound for the image, so that we can just provide a high resolution version and have it scaled down? (sorry, I didn't actually write the SymPy code, so maybe @thisch should look here too) |
Ah, I was only thinking of the notebook. I don't think we have any plan to do retina enhancements to the qtconsole, most of which limitations I think are really those of Qt itself. As for images coming from sympy, the main thing is that we have exposed the ability to specify the display size of images. If sympy wants 2x display, it will have to use this - it is not going to be automatic. |
What is that API? All I see are changes to Image. |
And regarding retina qtconsole, could we at least have an open issue for it? |
Where is the sympy code for image-based output? Does it use def _repr_png_(self):
metadata = dict(width=display_width, height=display_height)
return pngdata, metadata
Sure, #3537. |
https://github.com/sympy/sympy/blob/master/sympy/interactive/printing.py#L130 (comments on any part of that file welcome, actually). The resolution is set at https://github.com/sympy/sympy/blob/master/sympy/interactive/printing.py#L45. I'd like to make that twice as large and scale it down, so that it is always its current size but high resolution on a retina screen. |
Since this is LaTeX, we could also probably display a vector graphic, assuming it is supported everywhere on the pipeline. I think the issue is that LaTeX does well with formats like pdf and dvi and browsers do well with formats like svg. Maybe @thisch has an idea. |
This lets custom display functions (e.g. HTML) be used without any extra changes (see ipython#2234). possible downsides: * The previous code guarantees that only one format is published. If multiple figure formatters are registered, display will send them all. * If people for some reason disable the type-printers, then they will display the automatic figure display. Neither of these cases can come up unless people are messing with the formatters, and I think the first is actually an improvement.
use display instead of send_figure in inline backend hooks This lets custom display functions (e.g. HTML) be used without any extra changes (see ipython#2234). possible downsides: * The previous code guarantees that only one format is published. If multiple figure formatters are registered, display will send them all. * If people for some reason disable the type-printers, then they will display the automatic figure display. **Backwards-incompatible change** Note that `IPython.zmq.pylab.backend_inline.send_figure` has been removed, as `display()` can do the same job and we avoid an unnecessary special-case code path.
I have a retina MacBook Pro, and I've noticed that several of the images in IPython need to be updated to higher resolution so that they don't look bad. What I've noticed so far:
Note that you'll need to use Safari to test the notebook, as Chrome doesn't fully support retina graphics yet (Chrome Canary supports retina graphics, but not retina favicons).
This is only based on my little knowledge. Likely there are images and such for features that I don't know about that also need to be updated.
On non-retina Macs, you can test this by using Quartz Debug to increase the scaling to 2x.
Sorry if this seems low priority, but you really have to use a retina device to see just how bad non-retina things look.
The text was updated successfully, but these errors were encountered: