Skip to content

Scaling issue with 4K panel! #12221

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

Open
Khalilsqu opened this issue Sep 22, 2018 · 55 comments
Open

Scaling issue with 4K panel! #12221

Khalilsqu opened this issue Sep 22, 2018 · 55 comments
Labels
GUI: Qt keep Items to be ignored by the “Stale” Github Action OS: Microsoft status: upstream fix required

Comments

@Khalilsqu
Copy link

Matplotlib plots and font size looks very small on 4K monitor.

Is there away to automatically enable high DPI?

capture

@jklymak jklymak added the status: needs clarification Issues that need more information to resolve. label Sep 23, 2018
@jklymak
Copy link
Member

jklymak commented Sep 23, 2018

We'd need a lot more information before we can tell if this is a bug or not. Thanks!

@Khalilsqu
Copy link
Author

Khalilsqu commented Sep 24, 2018

I recently purchased a new pc laptop with 4K resolution touch screen.

when I run the following code while screen is at native max resolution of 4K. pyplot images and font sizes are displayed very tiny!!

import sys
import matplotlib
import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

print("screen resolution is {} by {}".format(w,h))

print(sys.platform)
print(sys.version)

print(matplotlib.__version__)
print(matplotlib.get_backend())

import matplotlib.pyplot as plt

plt.plot(range(100))

plt.show()

4k

But when I lower the screen resolution to FHD, 1920x1080 in the windows setting, the figures and font sizes becomes normal and good!

fhd

So, my question is how I can configure matplotlib to plot similarly both in UHD or FHD without the need to make changes in the code or use dragging. Please check the screen resolution in the code output shown in both figures above!. Dragging only makes plot bigger but font size of tick labels stay the same, unless I change them in the code

@jklymak
Copy link
Member

jklymak commented Sep 24, 2018

Qt5Agg should automatically detect if the screen dpi is doubled. It calls window.devicePixelRatio(). So, maybe your setup is too old to do that (2.2.3 does this, but I guess some old Qt5 versions don't) or your device isn't reporting that its pixel doubled.

If you want to set the dpi by hand, you can set the dpi rcParam.

If you want to debug, you can edit backend_qt5agg and put some print statements in def _dpi_ratio(self):

@ImportanceOfBeingErnest
Copy link
Member

ImportanceOfBeingErnest commented Sep 24, 2018

I think there is a fundamental difference between macOS and the rest of the world (or between HighDPI and high dpi). Macs may scale the dpi, effectively showing the application in a virtual dpi space. Windows does not do that. There is just one dpi; but it might instead use different profiles such that some relevant metrics are scaled by a constant factor (e.g. a 12pt font will become 24pt).

I suppose this article is relevant here. Possibly this blog post as well.
If I understand the above article correctly the application attribute Qt::AA_EnableHighDpiScaling could be used; but I'm not sure how that would play with the manual settings currently done within the qt painter method.

It was also reported that on windows devicePixelRatio() always returns 1 and a potential workaround would be to use logicalDpiX() instead.

One might think about making the _dpi_ratio publically available to the user and adjustable via rcParams.

For the time being the only option seems to be to change the true dpi, e.g. in this case the rc file may be changed to

figure.dpi  : 200
savefig.dpi : 100  # to avoid large graphics when saving, 

@Khalilsqu
Copy link
Author

Khalilsqu commented Sep 24, 2018

@ImportanceOfBeingErnest Thank you very much. actually matplotlib.rcParams['figure.dpi'] = 200 is the solution worked for me. tried tk, etc yet all cannot scale properly on 4K screen

@ImportanceOfBeingErnest ImportanceOfBeingErnest added GUI: Qt and removed status: needs clarification Issues that need more information to resolve. labels Sep 24, 2018
@ImportanceOfBeingErnest
Copy link
Member

Reopening, because this is surely a desireable feature, given that matplotlib goes through all the trouble of using different dpi values on different levels, but apparently only mac users will benefit from it.

@jklymak
Copy link
Member

jklymak commented Sep 24, 2018

I actually thinks it’s a pain that the Mac does this rather than just stating its true dpi. The advantage of allowing it to change is dragging between screens w different dpi. But in my opinion we should just get the dpi from the device at draw time.

@Khalilsqu
Copy link
Author

Khalilsqu commented Sep 24, 2018

There was a similar issue in spyder ide but recently solved in their latest releases. Spyder is basically using Qt5. I experienced scaling issue with spyder using 4K screen but resolved by enabling Enable auto high scaling in spyder settings. probably a similar approach could be applied to Matplotlib?

spyder-ide/spyder#4316
https://blog.qt.io/blog/2016/01/26/high-dpi-support-in-qt-5-6/

@jklymak
Copy link
Member

jklymak commented Sep 24, 2018

Thanks - so far as I can see we already do "Case II" in the blog post about QT above:

if is_pyqt5():
try:
qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
qApp.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)

So its odd that its not working for Qt5, unless you have an old Qt5, an environment variable set, or are somehow disabling this. You could download master and put a print statement above to see if your Qt5 has the correct attribute.

@Khalilsqu
Copy link
Author

Khalilsqu commented Sep 24, 2018

I modified the file in my current python installation folder as shown below. could not manage to build matplotlib from master! saying vs c++ and other headers are missing even after vs++ installation..

if is_pyqt5():
        try:
            qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
            qApp.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
            dim = qApp.desktop().screenGeometry()
            print("The screen resolution is ({} X {}):".format(dim.width(), dim.height()))

it prints the correct resolution whenever plotting any figures The screen resolution is (3840 X 2160): but still image and fonts sizes are very small

@timhoffm
Copy link
Member

To better understand what's going on, can you please also check the values of

qApp.desktop().logicalDpiX()
qApp.desktop().phyiscalDpiX()

@Khalilsqu
Copy link
Author

Khalilsqu commented Sep 24, 2018

    if is_pyqt5():
        try:
            qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
            qApp.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
            dim = qApp.desktop().screenGeometry()
            print("The screen resolution is ({} X {}):".format(dim.width(), dim.height()))
            print("logicalDpiX ", qApp.desktop().logicalDpiX())
            print("phyiscalDpiX ", qApp.desktop().phyiscalDpiX())

        except AttributeError:
            pass

output:

The screen resolution is (3840 X 2160):
logicalDpiX  240

qApp.desktop().phyiscalDpiX() goes to exception block!,

AttributeError: 'QDesktopWidget' object has no attribute 'phyiscalDpiX'

@timhoffm
Copy link
Member

sorry typo phyiscal -> physical

@Khalilsqu
Copy link
Author

Khalilsqu commented Sep 24, 2018

output

The screen resolution is (3840 X 2160):
logicalDpiX  240
physicalDpiX  284

@Khalilsqu
Copy link
Author

I solved the the problem by installing python from python.org website rather than anaconda/miniconda. matplotlib installed using pip. The backend is TkAgg and matplotlib version is 3.0.0. However, when changing the backend to Qt5Agg, scaling issue appears again!. To me backend does not matter as long as the plotted figures are in appropriate scale!!

@tacaswell tacaswell added this to the v3.0.x milestone Sep 27, 2018
@tacaswell
Copy link
Member

Does the documentation at https://doc.qt.io/qt-5.9/highdpi.html#operating-system-support help at all?

@adamsiembida
Copy link

There was a similar issue in spyder ide but recently solved in their latest releases. Spyder is basically using Qt5. I experienced scaling issue with spyder using 4K screen but resolved by enabling Enable auto high scaling in spyder settings. probably a similar approach could be applied to Matplotlib?

spyder-ide/spyder#4316
https://blog.qt.io/blog/2016/01/26/high-dpi-support-in-qt-5-6/

I just tested this in Spyder. Using their settings makes their GUI look better, but the plots don't really get any better. If you are plotting inline (inside of their app) the plot gets bigger, but more blurry (I think the image just gets scaled up). When you change the settings to use the QT5 backend (and the plot opens in a separate window) it is still tiny.

@ImportanceOfBeingErnest
Copy link
Member

Just to be clear, spyder does not change any matplotlib variables. The issue for spyder being mentionned in this thread is because their interface is based on QT as well, and hence any solution they have used might help with this issue.

This being said, @w1res if you experience the same issue, can you share as accurate as possible your system/version/windows graphics/dpi settings?

@Khalilsqu
Copy link
Author

I unfortunately returned the unit since I experienced some other issues with the laptop. Therefore, I apologise if not being able to provide any further testing with any 4K monitor since there is none I have now. My apologies to all of you.

@adamsiembida
Copy link

This being said, @w1res if you experience the same issue, can you share as accurate as possible your system/version/windows graphics/dpi settings?

I'm using a laptop with a 3840 x 2160 (4K) touch screen. The operating system is Windows 10 Pro version 1803. I'm using 200% scaling (default was 250%) in the operating system settings. My graphics card is the NVIDIA GTX 1050 TI.

@QuLogic
Copy link
Member

QuLogic commented Mar 31, 2022

All this would be done for you with latest Matplotlib and Qt.

Note that latest Qt is not available in conda-forge. This means you will not get good behaviour if running with fractional DPI. However, there appears to be some movement on the above issue for updating PyQt in conda-forge.

@karahanyilmazer
Copy link

karahanyilmazer commented Mar 31, 2022

Sorry, I think it should be fig.canvas._device_pixel_ratio

It depends on which screen I run the command from. If I run it from my high DPI laptop I get 2, if I run it from the external window I get 1.

I also noticed that somehow the plotting got better. In this GIF you can see the effect of running

plt.matplotlib.rcParams['figure.dpi'] = qApp.desktop().physicalDpiX()

However, the version before running this line is also pretty readable. I will update you if I notice any strange behavior.

Animation (0)

PS: This is not my whole screen that you see in the GIF

@tacaswell
Copy link
Member

One more odd test, can you please use

fig.set_size_inches(5, 5)

and then use a ruler to measure the size of the window on your screen in all of these cases? If you move the window between the low and high DPI screens does it resize in a reasonable way?

@karahanyilmazer
Copy link

One more odd test, can you please use

fig.set_size_inches(5, 5)

and then use a ruler to measure the size of the window on your screen in all of these cases? If you move the window between the low and high DPI screens does it resize in a reasonable way?

Sorry for the delay. I noticed that in my first call after restarting my high-DPI laptop, the scaling is off and the figure is very small. When I run the line _device_pixel_ratio I get 1. In this case, fig.set_size_inches(5, 5) produces a plot with a width and height of 5 cm.

Then I run plt.matplotlib.rcParams['figure.dpi'] = qApp.desktop().physicalDpiX(). This produces a large and readable window. Running fig.set_size_inches(5, 5) returns a plot with a width and height of about 12.7 cm and running _device_pixel_ratio returns 2.

Finally, when I close my Jupyter terminal or restart VS Code, I get a plot that is nicely scaled without needing to rerun plt.matplotlib.rcParams['figure.dpi'] = qApp.desktop().physicalDpiX(). In this case, fig.set_size_inches(5, 5) returns a plot with a width and height of about 10 cm (slightly smaller than the previous one) and running _device_pixel_ratio returns 2 again.

I hope this helps you with the troubleshooting.

@karahanyilmazer
Copy link

@tacaswell @QuLogic any news?

@QuLogic QuLogic modified the milestones: v3.6.0, v3.6.1 Sep 14, 2022
@oscargus
Copy link
Member

For what it's worth I just got a 4k laptop and noticed that same thing with the Qt backend. Not sure what the status is, but e.g. Spyder is working well (although I had to enable a switch in the preferences to have it scale properly). Given time, I can have a more in depth look at this now...

@oscargus
Copy link
Member

oscargus commented Sep 29, 2022

Spyder refers to https://doc.qt.io/qt-5/highdpi.html

The setting that made it work for me ends up like this in the code high_dpi_scaling is True when it works well:

QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling,
                                             CONF.get('main', 'high_dpi_scaling'))

I think a solution is to do something similar through a boolean RC param? (Although this may of course break some of the other fixed high DPI issues...)

@oscargus
Copy link
Member

oscargus commented Sep 29, 2022

@QuLogic QuLogic modified the milestones: v3.6.1, v3.6.2 Oct 6, 2022
@QuLogic QuLogic modified the milestones: v3.6.2, v3.6.3 Oct 27, 2022
@QuLogic QuLogic modified the milestones: v3.6.3, v3.7.0 Jan 11, 2023
@ksunden ksunden modified the milestones: v3.7.0, v3.7.1 Feb 14, 2023
@QuLogic QuLogic modified the milestones: v3.7.1, v3.7.2 Mar 4, 2023
@QuLogic QuLogic modified the milestones: v3.7.2, v3.7.3 Jul 5, 2023
@karahanyilmazer
Copy link

Are there any news regarding this issue? Still having high-DPI related problems on VS Code and I need to paste a chunk of code in the beginning of each script to overcome the issue. Thank you!

@tacaswell @QuLogic @oscargus

@QuLogic QuLogic modified the milestones: v3.7.3, v3.8.0 Sep 9, 2023
@ksunden ksunden removed this from the v3.8.0 milestone Sep 15, 2023
Copy link

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Sep 27, 2024
@oscargus oscargus added keep Items to be ignored by the “Stale” Github Action and removed status: inactive Marked by the “Stale” Github Action labels Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GUI: Qt keep Items to be ignored by the “Stale” Github Action OS: Microsoft status: upstream fix required
Projects
None yet
Development

No branches or pull requests