Ответ 1
Вы можете непосредственно определить, есть ли у вас дисплей с модулем ОС в Python. в моем случае это
>>> import os
>>> os.environ["DISPLAY"]
':0.0'
Я генерирую цифры matplotlib в script, который я запускаю в качестве альтернативы с графическим дисплеем или без него. Я бы хотел, чтобы script настраивался автоматически: с дисплеем он должен показывать фигуры в интерактивном режиме, а без дисплея - просто сохранять их в файл.
Из ответа на вопрос Создание графиков 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 или нет?
Вы можете непосредственно определить, есть ли у вас дисплей с модулем ОС в Python. в моем случае это
>>> import os
>>> os.environ["DISPLAY"]
':0.0'
попробуйте это?
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()
Код ниже работает для меня в Linux и Windows (предполагалось, что есть устройство отображения):
import os
import matplotlib
if os.name == 'posix' and "DISPLAY" not in os.environ:
matplotlib.use('Agg')
См. fooobar.com/questions/47848/....
Обратите внимание, что строка matplotlib.use('Agg')
должна появиться после первого импорта matplotlib
(иначе вы получите сообщение об ошибке).
Объединив оба подхода выше, вы получите, возможно, лучшее решение:
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).
когда используется GUI-сервер, объект фигуры имеет метод 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")
Решение, предлагаемое @Oz123, вызвало синтаксическую ошибку для меня. Тем не менее, я смог легко обнаружить дисплей, используя:
import os
havedisplay = "DISPLAY" in os.environ
#plotting...
Это была самая простая вещь, которую я мог найти, во всяком случае.