Savefig не правильно сохраняет отображаемый график - PullRequest
0 голосов
/ 15 мая 2018

Я рисую фигуру на весь экран и хочу сохранить ее в .png с помощью savefig. В результате изображение намного меньше, чем на рисунке. И дело не в dpi (общая цифра меньше, но шрифты и ширина линии имеют правильный размер, поэтому, если я увеличу dpi, шрифт увеличится слишком сильно). Вот очень простой пример, чтобы вы могли воспроизвести его:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0,10,0.01)
y1 = np.sin(x)
y2 = np.sin(3*x)
y3 = np.sin(5*x)

fig, ax = plt.subplots()
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
plt.subplots_adjust(bottom=0.09, top=0.96, right=0.97, left=0.07)

plt.plot(x,y1, 'C0', linewidth = 2)
plt.plot(x,y2, 'C1', linewidth = 2)
plt.plot(x,y3, 'C2', linewidth = 2)

plt.xlabel('x label', fontsize=18)
plt.ylabel('y label', fontsize=18)
plt.xticks(color='k', size=16)
plt.yticks(color='k', size=16)
plt.grid()
plt.legend(['blue', 'red', 'green'], fontsize=16)

fig.savefig('coco_gcf-dpi.png', dpi=plt.gcf().dpi, bbox_inches = 'tight')
fig.savefig('coco_200dpi.png', dpi=200, bbox_inches = 'tight')
plt.show()    

Вы можете видеть, что сохраненные графики отличаются от графиков, отображаемых на вашем экране. И увеличение dpi не помогает.

Я должен также указать, что я использую Python 3.6 и Spyder 3.2.8 с бэкэндом Qt5. Если кому-то удастся изменить этот код, чтобы отображаемая фигура была правильно сохранена (тот же общий размер, тот же размер шрифта, та же толщина линии), я был бы очень признателен!

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Похоже, showMaximized() был применен только к отображаемому рисунку, а не к сохраненному, поэтому единственное решение, которое я нашел, - это избавиться от showMaximized(), найти размер экрана с помощью tkinter и использовать ихразмеры для указания размера рисунка:

import tkinter as tk
root = tk.Tk()
width = root.winfo_screenwidth()
height = root.winfo_screenheight()

возвращает высоту и ширину экрана в пикселях

mydpi = 100
fig, ax = plt.subplots(figsize=(width/mydpi, height/mydpi), dpi=mydpi)

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

Наконец, полный код:

import numpy as np
import matplotlib.pyplot as plt
import tkinter as tk

root = tk.Tk()
width = root.winfo_screenwidth()
height = root.winfo_screenheight()

mydpi = 100
x = np.arange(0,10,0.01)
y1 = np.sin(x)
y2 = np.sin(3*x)
y3 = np.sin(5*x)

fig, ax = plt.subplots(figsize=(width/mydpi, height/mydpi), dpi=mydpi)
plt.subplots_adjust(bottom=0.09, top=0.96, right=0.97, left=0.07)

plt.plot(x,y1, 'C0', linewidth = 2)
plt.plot(x,y2, 'C1', linewidth = 2)
plt.plot(x,y3, 'C2', linewidth = 2)

plt.xlabel('x label', fontsize=18)
plt.ylabel('y label', fontsize=18)
plt.xticks(color='k', size=16)
plt.yticks(color='k', size=16)
plt.grid()
plt.legend(['blue', 'red', 'green'], fontsize=16)

fig.savefig('coco_gcf-dpi.png', dpi=plt.gcf().dpi, bbox_inches = 'tight')
plt.show()

И вот, наконец, мой график сохранен в точности так, как я вижу его на моем экране.!

0 голосов
/ 15 мая 2018

Последние несколько строк вашего скрипта должны выглядеть так:

plt.tight_layout()
fig.savefig('coco_gcf-dpi.png', dpi=plt.gcf().dpi)
fig.savefig('coco_200dpi.png', dpi=200)
plt.show()

Использование plt.tight_layout обеспечивает плотную компоновку как для сохраненных, так и для интерактивно отображаемых фигур. Они были такими, какими вы их изначально имели, плотная разметка применялась только к сохраненным фигурам.

...