используйте Python plt.plot () для построения рисунка без появления окна графика графика [дубликат]

Ну так много хороших ответов, я хочу добавить еще об этом. Это поможет понять Extending v/s Implementing Thread .Extends очень тесно связывает два файла класса и может привести к довольно сложному решению кода.

Оба подхода выполняют одну и ту же работу, но были некоторые различия. Наиболее распространенным отличием является

  1. Когда вы расширяете класс Thread, после этого вы не можете расширять любой другой класс, который вам нужен. (Как вы знаете, Java не позволяет наследовать более одного класса).
  2. Когда вы реализуете Runnable, вы можете сохранить пространство для своего класса для расширения любого другого класса в будущем или сейчас.

Однако, одна существенная разница между реализацией Runnable и продолжением Thread заключается в том, что by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.

Следующий пример помогает вам более четко понять

//Implement Runnable Interface...
 class ImplementsRunnable implements Runnable {

private int counter = 0;

public void run() {
    counter++;
    System.out.println("ImplementsRunnable : Counter : " + counter);
 }
}

//Extend Thread class...
class ExtendsThread extends Thread {

private int counter = 0;

public void run() {
    counter++;
    System.out.println("ExtendsThread : Counter : " + counter);
 }
}

//Use above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {

public static void main(String args[]) throws Exception {
    // Multiple threads share the same object.
    ImplementsRunnable rc = new ImplementsRunnable();
    Thread t1 = new Thread(rc);
    t1.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    Thread t2 = new Thread(rc);
    t2.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    Thread t3 = new Thread(rc);
    t3.start();

    // Creating new instance for every thread access.
    ExtendsThread tc1 = new ExtendsThread();
    tc1.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    ExtendsThread tc2 = new ExtendsThread();
    tc2.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    ExtendsThread tc3 = new ExtendsThread();
    tc3.start();
 }
}

Вывод вышеуказанной программы.

ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1

В интерфейсе интерфейса Runnable создается только один экземпляр класса, и он был разделен разными потоками. Таким образом, значение счетчика увеличивается для каждого доступа к потоку.

В то время как подход класса Thread, вы должны создать отдельный экземпляр для каждого потока. Следовательно, для каждого экземпляра класса выделяется различная память, и каждый имеет отдельный счетчик, значение остается таким же, что означает, что приращение не произойдет, потому что ни одна из ссылок на объекты не является такой же.

Когда использовать Runnable? Используйте интерфейс Runnable, если вы хотите получить доступ к одному и тому же ресурсу из группы потоков. Избегайте использования класса Thread здесь, потому что создание нескольких объектов потребляет больше памяти, и это становится большой служебной нагрузкой.

Класс, который реализует Runnable, не является нитью и просто классом. Чтобы Runnable стал потоком, вам нужно создать экземпляр Thread и передать себя в качестве цели.

В большинстве случаев интерфейс Runnable должен использоваться, если вы только планируете переопределить run() и других методов Thread. Это важно, потому что классы не должны подклассифицироваться, если программист не намерен модифицировать или улучшать фундаментальное поведение класса.

Когда необходимо расширить суперкласс, реализация интерфейса Runnable более подходит, чем использование класс Thread. Потому что мы можем расширять другой класс при реализации интерфейса Runnable для создания потока.

Надеюсь, это поможет!

281
задан Joel 8 August 2016 в 23:37
поделиться

11 ответов

Основная проблема заключается в том, что (в вашей системе) matplotlib по умолчанию использует x-using бэкэнд. У меня была одна и та же проблема на одном из моих серверов. Решение для меня заключалось в том, чтобы добавить следующий код в место, которое читает перед любым другим импортом pylab / matplotlib / pyplot:

import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')

Альтернативой является установка его в ваш .matplotlibrc

475
ответ дан Reinout van Rees 18 August 2018 в 19:49
поделиться
  • 1
    +1 для параметра .use для указания бэкэнд. – Noufal Ibrahim 17 June 2010 в 12:08
  • 2
    Важное примечание: необходимо вызывать .use перед тем, как импортировать pyplot. Так что если вы, например, просто пытаетесь импортировать pyplot, вам нужно сначала импортировать matplotlib, использовать вызов и импортировать pyplot. – seaotternerd 8 November 2013 в 11:15
  • 3
    Вышеприведенный комментарий больше объясняется этим ответом . – Ioannis Filippidis 28 February 2014 в 08:15
  • 4
    backend: agg в ~/.config/matplotlib'/matplotlibrc (например, см. http: //matplotlib.org/faq/troubleshooting_faq.html#locating-matplotlib-config-dir). См. Также matplotlib.org/users/customizing.html , в котором есть пример файла конфигурации внизу страницы. Найти & quot; agg & quot; на этой странице, и вы увидите нужный вариант конфигурации. – Reinout van Rees 6 July 2015 в 08:48
  • 5
    Для справки, здесь ссылка на документацию matplotlib, которая объясняет это. (+1, отличный ответ, мне очень понравилось!) – Tim S. 4 February 2016 в 21:24

Еще одна вещь, чтобы проверить, разрешен ли ваш текущий пользователь для подключения к X-дисплею. В моем случае root не был допущен к этому, и matplotlib жаловался на ту же ошибку.

user@debian:~$ xauth list         
debian/unix:10  MIT-MAGIC-COOKIE-1  ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xauth add debian/unix:10  MIT-MAGIC-COOKIE-1 ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xterm

source: http://www.debian-administration.org/articles/494 https://debian-administration.org/article/494/Getting_X11_forwarding_through_ssh_working_after_running_su

2
ответ дан Alex 18 August 2018 в 19:49
поделиться

Чистый ответ - потратить немного времени на правильную подготовку среды выполнения.

Первым методом, который вы должны подготовить среду исполнения, является использование файла matplotlibrc, как разумно рекомендованный Крисом К. , установив

backend : Agg

в этом файле. Вы можете даже контролировать - без изменений кода - , как и где ищет matplotlib, и находит файл matplotlibrc .

Второй метод, который вы должны подготовить для своей среды выполнения, - это используйте переменную среды MPLBACKEND (и сообщите своим пользователям об использовании):

export MPLBACKEND="agg"
python <program_using_matplotlib.py>

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

Жесткое кодирование вашего backplan matplotlib для «Agg» в вашем коде на Python похоже на избиение квадратный колышек в круглое отверстие с большим молотком, когда вместо этого вы могли просто сказать matplotlib, что это должно быть квадратное отверстие.

36
ответ дан Community 18 August 2018 в 19:49
поделиться
  • 1
    Вторая техника выглядит как самая элегантная в этой ситуации. – Dmitry Kabanov 17 October 2017 в 20:22
  • 2
    Использование MPLBACKEND решило это для меня. Определенно самый изящный способ! – SaturnFromTitan 18 May 2018 в 04:32

При входе в сервер для выполнения этого кода используйте это:

ssh -X username@servername

-X избавится от отображаемого имени без знака переменной DISPLAY

:)

12
ответ дан DaveShaw 18 August 2018 в 19:49
поделиться
  • 1
    Мне нужно использовать '-X', чтобы сохранить .png-изображение. Большое спасибо. – nos 13 March 2012 в 00:02
  • 2
    это тот, который работал на меня. – jason 12 April 2014 в 22:57
  • 3
    Это не удастся для длительного процесса, если ssh не работает, или если вам нужно отключиться по какой-либо причине. Обратите внимание, что таймаут может даже произойти, если подключаемый клиент переходит в спящий режим. – posdef 13 December 2016 в 17:00

Как дополнение к ответу Рейно.

Постоянный способ решить эту проблему - отредактировать файл .matplotlibrc. Найдите его через

>>> import matplotlib
>>> matplotlib.matplotlib_fname() # This is the file location in Ubuntu '/etc/matplotlibrc'

Затем измените бэкэнд в этом файле на backend : Agg. Вот и все.

67
ответ дан Devendra Desale 18 August 2018 в 19:49
поделиться
  • 1
    Pro tip: установите $MATPLOTLIBRC в каталог , где вы хотите бросить свой собственный matplotlibrc. – Kenneth Hoste 29 August 2013 в 19:19
  • 2
    Kinda overkill для такой проблемы, но я предполагаю, что если сервер всегда работает без головы, имеет смысл модифицировать конфигурационный файл. Будет ли это иметь какие-либо побочные эффекты от того, как будет функционировать matplotlib? – BruceJohnJennerLawso 13 September 2016 в 01:45
  • 3
    Я бегу matplotlib на веб-сервере, так что это был ответ для меня. Я не заметил никаких побочных эффектов. – spitz 25 November 2017 в 13:14

Я получил ошибку при использовании matplotlib через Spark. matplotlib.use('Agg') не работает для меня. В конце концов, для меня работает следующий код. Подробнее здесь

import matplotlib.pyplot as plt.
plt.switch_backend('agg')
25
ответ дан Jeril 18 August 2018 в 19:49
поделиться
  • 1
    Замечательно :) Спасибо. – Nikolay Fominyh 4 August 2017 в 22:20
  • 2
    Это отлично работает, без ограничений на порядок, используемый для импорта matplotlib и других библиотек. – PabTorre 5 September 2017 в 15:40
  • 3
    При запуске на Spark вам пришлось ограничивать это для запуска на головном узле, или вы его работали при работе на рабочих узлах? – Saca 24 September 2017 в 06:57
  • 4
    Я использую это в проекте django, и это был единственный способ заставить его работать. – HenryM 3 February 2018 в 17:28
  • 5

Для Google Learning Engine Engine:

import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages

И затем для печати в файл:

#PDF build and save
    def multi_page(filename, figs=None, dpi=200):
        pp = PdfPages(filename)
        if figs is None:
            figs = [mpl.pyplot.figure(n) for n in mpl.pyplot.get_fignums()]
        for fig in figs:
            fig.savefig(pp, format='pdf', bbox_inches='tight', fig_size=(10, 8))
        pp.close()

и для создания PDF:

multi_page(report_name)
0
ответ дан Kim Miller 18 August 2018 в 19:49
поделиться

Я обнаружил, что этот фрагмент хорошо работает при переключении между средами X и no-X.

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using non-interactive Agg backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt
8
ответ дан Matthias123 18 August 2018 в 19:49
поделиться
  • 1
    На мой взгляд, это превосходное решение, чем принятое, хотя оно прямо не отвечает на вопрос и отвечает на заданный вопрос. – Dale Smith 14 February 2017 в 12:53

В какой системе вы работаете? Похоже, у вас есть система с X11, но переменная среды DISPLAY была неправильно настроена. Попробуйте выполнить следующую команду, а затем повторно запустить вашу программу:

export DISPLAY=localhost:0
4
ответ дан Michael Aaron Safyan 18 August 2018 в 19:49
поделиться
  • 1
    но почему это необходимо для установки отображаемой переменной, я удаленно зарегистрирован на этом сервере, все, что он должен делать, это сгенерировать PNG-файл ??? – krisdigitx 10 May 2010 в 11:41
  • 2
    @krisdigitx, если вы дистанционно подключены, не устанавливайте отображаемую переменную; вместо этого используйте "-XY" флаг при подключении. Чтобы отобразить, ему нужно знать, к какому Xserver нужно отправить изображение; в этом случае это будет отображение вашего компьютера, а не удаленного компьютера. Использование "-XY" флаг заставляет SSH автоматически устанавливать переменную DISPLAY, указывая на отображение подключаемого компьютера. – Michael Aaron Safyan 10 May 2010 в 15:12
  • 3
    @krisdigitx, я согласен, очень странно, что он это делает; однако я предполагаю, что он рисует изображение с помощью X11, а затем сохраняет результат с помощью X11. – Michael Aaron Safyan 10 May 2010 в 15:14
  • 4
    Использование этого параметра для $ DISPLAY не работает на EC2, запущенном Ubuntu 16 - не удалось подключиться к отображению "localhost: 0 & quot; – PabTorre 5 September 2017 в 15:39

import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt

Это работает для меня.

2
ответ дан Qing En 18 August 2018 в 19:49
поделиться

Я просто повторю то, что сказал @ Иво Бостицки, которого можно упустить. Поместите эти строки в ОЧЕНЬ старт файла py.

import matplotlib
matplotlib.use('Agg') 

Или получится ошибка

*/usr/lib/pymodules/python2.7/matplotlib/__init__.py:923: UserWarning:  This call to   matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,*

Это решит проблему отображения

30
ответ дан the Tin Man 18 August 2018 в 19:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: