Автоматическое определение доступности дисплея с помощью matplotlib - PullRequest
14 голосов
/ 24 ноября 2011

Я генерирую фигуры matplotlib в сценарии, который я запускаю поочередно с графическим дисплеем или без него.Мне бы хотелось, чтобы скрипт настраивался автоматически: при отображении он должен отображать цифры в интерактивном режиме, а без отображения - просто сохранять их в файл.

Из ответа на вопрос Создание графиков matplotlib без запущенного X-сервера , я узнал, что можно использовать бэкэнд Agg для неинтерактивного черчения.

я пытаюсь с этим кодом:

import matplotlib
try:
    import matplotlib.pyplot as plt
    fig = plt.figure()
    havedisplay = True
except:
    matplotlib.use("Agg")
    import matplotlib.pyplot as plt
    fig = plt.figure()
    havedisplay = False
# do the plotting
if havedisplay:
    plt.show()
else:
    fig.savefig("myfig.png")

Это работает как исключение в случае с дисплеем.Однако без дисплея вызов matplotlib.use не эффективен, поскольку дисплей уже выбран.Ясно, что я должен вызвать matplotlib.use до import matplotlib.pyplot, но тогда я не знаю, как проверить, доступен ли дисплей.

Я также попробовал с экспериментальной функцией matplotlib.switch_backend вместоиз matplotlib.use, но при этом возникает RuntimeError.

Есть ли у кого-нибудь идеи, как заставить вышеуказанный код работать как задумано, или может предложить альтернативный способ определения, доступен ли дисплей для matplotlib или нет?

Ответы [ 7 ]

15 голосов
/ 24 ноября 2011

Вы можете напрямую определить, есть ли у вас дисплей с модулем ОС на python.в моем случае это

>>> import os
>>> os.environ["DISPLAY"]
':0.0'
5 голосов
/ 24 ноября 2011

попробуйте это?

import matplotlib,os
r = os.system('python -c "import matplotlib.pyplot as plt;plt.figure()"')
if r != 0:
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    fig = plt.figure()
    fig.savefig('myfig.png')
else:
    import matplotlib.pyplot as plt
    fig = plt.figure()
    plt.show()
4 голосов
/ 18 августа 2017

Код ниже работает для меня в Linux и Windows (если предполагается, что устройство отображения):

import os
import matplotlib
if os.name == 'posix' and "DISPLAY" not in os.environ:
    matplotlib.use('Agg')

См. https://stackoverflow.com/a/1325587/896111.

Обратите внимание, что строка matplotlib.use('Agg') должна появиться после первого импорта matplotlib (в противном случае вы получите ошибку).

3 голосов
/ 28 мая 2015

Комбинируя оба подхода, вы получите, возможно, лучшее решение:

havedisplay = "DISPLAY" in os.environ
if not havedisplay:
    exitval = os.system('python -c "import matplotlib.pyplot as plt; plt.figure()"')
    havedisplay = (exitval == 0)

Причина этого комбо состоит в том, что время выполнения команды os.system может занять некоторое время. Поэтому, когда вы уверены, что у вас есть дисплей (судя по значению os.environ), вы можете сэкономить это время. С другой стороны, даже если ключ DISPLAY не задан в переменной os.environ, существует вероятность того, что методы построения графиков будут работать с графическим интерфейсом (например, при использовании командной строки Windows).

1 голос
/ 20 января 2015

Решение, предложенное @ Oz123, вызвало синтаксическую ошибку для меня. Тем не менее, я смог легко обнаружить дисплей с помощью:

import os
havedisplay = "DISPLAY" in os.environ
#plotting...

В любом случае, это было самое простое, что я мог найти.

1 голос
/ 24 ноября 2011

при использовании графического интерфейса пользователя у объекта figure есть метод show (), его можно использовать для переключения:

import matplotlib
#matplotlib.use("Agg")

import matplotlib.pyplot as plt
fig = plt.figure()
havedisplay = False
if hasattr(fig, "show"):
    plt.show()
else:
    print "save fig"
    fig.savefig("myfig.png")
0 голосов
/ 12 марта 2019
import os
have_display = bool(os.environ.get('DISPLAY', None))

have_display имеет значение False, если DISPLAY отсутствует в среде или является пустой строкой. в противном случае это правда

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...