I use Bokeh to plot some interactive charts for my project, the Bokeh app runs on server. I like these charts can be plotted in full size on clients' browsers no matter what local resolution would be. Could someone give me a clue on how to get remote screen's max size?
I tried selenium, which asks user install drivers on local computer. It is not a good idea.
Also I tried python win32 API, which gets server's not remote computer's resolution.
Thanks
I don't know how to get the screen's size, but I have made my bokeh figures take up the full browser window (not necessarily full screen, but would be if the browser was full screen).
Instead of:
figure(plot_width = ... , plot_height = ... , ...)
I used:
figure(sizing_mode="stretch_both", ...)
("scale_both" is an alternative, which keeps the height/width ratio if you set those too).
Info from bokeh documentation.
Related
this is probably not much of a coding question.
I developed an application in Tkinter which consists pretty much in a canvas where I load images on (matplots).
When I run it from Spyder or Jupyter notebook I obtain 143 DPI and when I run it directly in terminal I obtain 95 DPI instead.
The most weird thing is that once I run it from terminal it shows as if it was a 143 DPI application but when I load the image the app decides to resize completely and then change the DPI of my screen. So the whole thing resizes, buttons, pop up boxes and etc...
It is very important to me that I can run it from terminal, because afterwards I will transform it into a .exe application.
My first approach was to use the tkinter method .winfo_fpixel() and try to ratio the DPIs and multiply it to every dimension in the application.
Later I tried to find python.exe and pythonw.exe in order to change the compatibility with HIGH DPI Scale.
Do you thing there is a way to solve this without resizing everything?
I would like to insist that I'm 100% sure this has nothing to do with the code, therefore I might not post any coding samples.
Thanks.
obs: I use Windows 10
ps: I tried to run the app with two screens, what happened was really funny, when I use it on an adequate screen it runs normally, but when I slide it to the other screen and make any action/event it will resize it automatically.
selbie's answer is correct.
Also,You could use winapi to set DPI aware in python directly(this could work in tkinter):
import ctypes, tkinter
try: # >= win 8.1
ctypes.windll.shcore.SetProcessDpiAwareness(2)
except: # win 8.0 or less
ctypes.windll.user32.SetProcessDPIAware()
root = tkinter.Tk()
....
MSDN doc: SetProcessDpiAwareness, MSDN doc: SetProcessDPIAware
And this is another answer which mentioned about DPI awareness.
DPI is largely influenced by your PC's resolution settings - specifically the setting on "Scale and layout". 100% is 96 DPI and 150% is 144 DPI. I'm guessing it's just a rounding error from your app that's showing 95 and 143. Laptops tend to have higher resolution screens, so OEM's default to >100% setting so that you don't have to squint to see your apps. Whereas, your typical 1080p display defaults to 100% DPI. But when you "remote desktop" into a PC, Windows may re-adapt and re-stretch the DPI settings to match the local display if its DPI and resolution are different.
Windows will auto-scale most applications that haven't explicitly set their "DPI awareness" with the OS. That's typically fine for most application (although they can appear "blurry"). Applications can be compiled to be dpi aware are not stretched except in certain multi-monitor situations. This is especially likely for graphics applications. And that's where bugs like the one you are seeing tend to show up. You can often change this behavior by right clicking on the EXE, clicking Properties, and finding the setting the compatibility tab:
The most weird thing is that once I run it from terminal it shows as if it was a 143 DPI application but when I load the image the app decides to resize completely and then change the DPI of my screen. So the whole thing resizes, buttons, pop up boxes and etc...
When you remoted into your PC, the system DPI changed. Applications can get confused - especially if they aren't adapting to a changing DPI setting. Or worse, the application registers with Windows that it is DPI aware, but doesn't handle the corner case of when the monitor is swapped out - which is effectively what happens when you remoted into it. You can however, override this behavior with some combination of the Properties dialog above and the available APIs to control dpi-awareness.
I don't much about TKinter (Does it use the Python process or is it its own exe?). If you can compile it yourself, you can use the various Windows APIs and manifest settings to get the DPI behavior you want. My shot in the dark guess is that TKinter( is declaring itself per-monitor dpi-aware, but has a bug that doesn't account for the DPI changing on the fly. Typical fix for this situation is to just restart the application.
Everything you need to know at the links below:
https://learn.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows
https://learn.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
https://msdn.microsoft.com/en-us/C9488338-D863-45DF-B5CB-7ED9B869A5E2
You can also read my previous answers regarding DPI awareness in Windows apps:
https://stackoverflow.com/search?q=user%3A104458+dpi
I'm taking screenshots with selenium from a remote server. When the screenshots are taken from my local computer, everything works fine. But some of the screenshots from the remote server are coming with a dark black shadow over some elements.
here is how the screenshot looks like
In the black area must have some content. And after changing some color properties, we can see that the content is there actually. The weirdness in my opinion, is the fact that some elements are just fine. I already tried to increase the wait before taking the screenshot and the method used for(selenium has more than one method for taking screenshots).
self.driver.set_window_size(self.width, total_height)
timefrommoduletime.sleep(self.minimum_sleep_between_actions + 5)
self.driver.save_screenshot(path)
I have been working through the tutorials on pyviz.org. specifically the dashboard one
If I setup the example here: http://pyviz.org/tutorial/A2_Dashboard_Workflow.html
The save icon in the bokeh plot appears to be disabled. If I click area zoom, wheel zoom,or the reset icon they behave as expected. But the save button does nothing.
Is this intentional, able to be reset, or a bug on my side?
Ben
This is a fundamental limitation of browsers, the issue is that the map tiles in the background are making cross-origin requests to download the tiles. Browsers consider this a security issue and therefore mark the canvas as tainted. If you look at the browser console you'll see this error message when hitting save:
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
In recent versions of GeoViews we therefore automatically disable the save tool if a tile source is present, but the website was built using an older version.
TL;DR: It's a browser security issue and cannot be resolved afaik.
So I've been trying to learn Bokeh recently and everything was going well but suddenly whenever I try and make a Bokeh plot the browser just shows a blank page. I get no error codes just the blank page. This is with programs that I was successfully using to create plots just a couple days ago. I even tried loading a html plot file I'd made a few weeks ago that had worked on co-workers computers and got the same result. I even tried one of the basic example code and got the same blank page.
from bokeh.plotting import figure, output_file, show
p = figure(title="line", plot_width=300, plot_height=300)
p.line(x=[1, 2, 3, 4, 5], y=[6, 7, 2, 4, 5])
show(p)
Never thought to try it but do standard Bokeh plots work if you are not online? Does it callout to an external server to generate the plots and maybe now some IT changes at my work are preventing the plots from being generated?
Thanks for any help!
It does not call out to an external server, but it does require the browser to load a JavaScript library, BokehJS. By default (and by popular demand) BokehJS is loaded remotely from a CDN (specifically, from https://cdn.bokeh.org). Accordingly, viewing a Bokeh plot that is configured to use CDN resource requires an active and working network connection.
But it's possible to use "inline" resources, which means the BokehJS library is included directly in the HTML output that Bokeh (the python library) generates. The easiest way to to do this is to set the environment variable:
BOKEH_RESOURCES=inline
There are other ways to specify resources, though, too. For more details see the documentation.
As an aside, in a situation like this it is helpful to consult your browser's JavaScript console. If the CDN resources can't be loaded, you will see the error there.
I intend to makea wx python application that can request and show the google map (or map from another similar map service) for a specific set of coordinates.
The application should:
Show a particular section of the map, rather than the whole screen.
Be able to adjust the resolution/magnification of image.
Be able to show map view and satelite image.
Where do I start?
Where to start:
import wx
Now that I have that out of my system :-) ... The first place you should start is to determine if wx can host a browser capable of displaying google maps. wxPython on windows can natively host IE so you could use that for displaying google maps on windows. (Dig around in the demo)
I am not sure if you can host Mozilla or Chrome inside a wx application. So, first determine if you can even display google maps in a wx app.
There is no pre-made widget that can do this for you. wxPython does have a WebView widget, starting in wxPython 2.9, that uses a web browser on the backend and is a bit more robust than the ActiveX version of the widget that was in older versions of wx. You could use that to display the map. Note that you will still need to figure out how to send Google API commands to the wrapped browser instance to manipulate the map.
You might also take a look at PySlip, which can be used to display large images in a tiled manner: https://code.google.com/p/pyslip/wiki/Introduction