2013-07-18 1 views
8

Итак, я рисую форму волны (и другие вещи), которые приводят к большему векторному файлу (PDF), чем соответствующий растровый файл (PNG). Я предполагаю, что это связано с тем, что построенный набор данных очень велик, и в векторном файле есть миллионы инструкций. Помимо того, что PDF-файл слишком большой, PDF-файл также довольно сложно отобразить. Для некоторых требуется несколько секунд для загрузки; на других он вообще не загружается.matplotlib bitmap plot с векторным текстом

В pyplot, возможно ли иметь растровое изображение с векторными осями, надписями и всем остальным текстом?

Мое (очень плохое) решение на данный момент состоит в том, чтобы сгенерировать PDF-файл, сгенерировать PNG, открыть PDF с помощью inkscape и заменить график на PNG-файл. Очевидно, что это слишком ручная и очень трудоемкая, если вы понимаете, что вам нужно восстановить сюжет.

+0

Читая подробные комментарии недавних (продолжается?) Обследования Matplotlib, другой человек сделал этот же запрос. https://docs.google.com/spreadsheet/ccc?key=0AjrPjlTMRTwTdHpQS25pcTZIRWdqX0pNckNSU01sMHc&usp=sharing – esmit

ответ

10

Это должно быть так же просто, как передать rasterized=True команде plot.

E.g.

import matplotlib.pyplot as plt 

plt.plot(range(10), rasterized=True) 
plt.savefig('test.pdf') 

Для меня это приводит в формате PDF с растрированной линией (разрешение контролируются точками на дюйм, указанные с savefig - по умолчанию это 100) и векторный текст.

+0

Я просто понял, что я никогда не отмечал это как правильный ответ, хотя с тех пор я его использую. Это именно то, что я искал, я не знаю, как я пропустил это в документах. Большое спасибо! – gozzilli

1

Я использую грязное «исправление» для этой проблемы. Я просто делаю сюжет дважды. После удаления всех фреймов, заголовков и т. Д. И сохранения в виде png, а в другом случае я удаляю фактические данные и сохраняю все компоненты, которые я хочу в качестве векторных данных в pdf. Затем я использую ImageMagick для преобразования png в pdf-файл, содержащий растровые данные, и накладываю векторные данные из pdf с помощью pdftk. Вот пример pcolor на странице matplotlib, адаптированный так, как я только что описал.

import matplotlib.pyplot as plt 
import numpy as np 
import os 

for case in ['frame','data']: 

    # make these smaller to increase the resolution                         
    dx, dy = 0.02, 0.02 

    # generate 2 2d grids for the x & y bounds                          
    y, x = np.mgrid[slice(-3, 3 + dy, dy), 
        slice(-3, 3 + dx, dx)] 
    z = (1 - x/2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2) 
    # x and y are bounds, so z should be the value *inside* those bounds.                    
    # Therefore, remove the last value from the z array.                        
    z = z[:-1, :-1] 
    z_min, z_max = -np.abs(z).max(), np.abs(z).max() 


    fig=plt.figure() 
    ax=fig.add_subplot(1,1,1) 
    im=plt.pcolor(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max) 
    plt.title('pcolor') 
    # set the limits of the plot to the limits of the data                       
    plt.axis([x.min(), x.max(), y.min(), y.max()]) 

    if case is 'frame': 
     im.remove() 
     plt.savefig("frame.pdf",transparent=True) 
    if case is 'data': 
     ax.axison=False 
     plt.title('') 
     plt.savefig("data.png",transparent=True) 



os.system('convert data.png data.pdf') 
os.system('pdftk frame.pdf background data.pdf output final_plot.pdf') 
os.system('rm data.png data.pdf frame.pdf') 

В основном это просто автоматизирована версия о том, что вы уже делаете ...

+1

Приятный трюк, но ответ от @Joe Kington прост и чист. Я действительно рекомендую попробовать этот вариант! – gozzilli

+0

Правда, действительно. Делает все проще. Я понимаю, что у меня было неправильное представление о том, что делает этот вариант растеризации ... –