2013-06-03 12 views
7

Tôi gặp vấn đề lạ. Sử dụng máy tính xách tay IPython, tôi tạo ra một kịch bản khá rộng rãi bằng cách sử dụng gấu trúc và matplotlib để tạo ra một số biểu đồ. Khi tinkering của tôi được hoàn thành, tôi sao chép (và làm sạch) mã thành một tập lệnh python độc lập (để tôi có thể đẩy nó vào svn và các đồng tác giả giấy của tôi cũng có thể tạo ra các biểu đồ).Tại sao âm mưu matplotlib được sản xuất từ ​​máy tính xách tay ipython hơi khác so với phiên bản đầu cuối?

Để thuận tiện, tôi nhập khẩu các python script độc vào máy tính xách tay một lần nữa và tạo ra một số bảng xếp hạng:

import create_charts as cc 
df = cc.read_csv_files("./data") 
cc.chart_1(df, 'fig_chart1.pdf') 
... 

đủ Strange, file .pdf tôi nhận được bằng cách sử dụng phương pháp trên là hơi khác nhau từ. tập tin pdf tôi nhận được khi tôi chạy kịch bản python độc lập của tôi từ thiết bị đầu cuối Windows 7 của tôi. Điểm khác biệt đáng chú ý nhất là trong một biểu đồ cụ thể, chú giải nằm ở góc trên thay vì góc dưới. Nhưng cũng có những khác biệt nhỏ khác nhau (giới hạn kích thước hộp, phông chữ có vẻ hơi khác)

Điều gì có thể là nguyên nhân của việc này. Và làm cách nào tôi có thể khắc phục sự cố? (tôi đã tắt máy tính xách tay của tôi và khởi động lại nó, để tái nhập khẩu create_charts kịch bản của tôi và bác bỏ bất kỳ thay đổi chưa được lưu) báo cáo thiết bị đầu cuối của tôi Tôi đang sử dụng Python 2.7.2, và pip freeze | grep ipython báo cáo ipython 0.13.1

Trả lời

3

Mở rộng câu trả lời của Matt (nhiều tín dụng cho anh ấy, nhưng tôi nghĩ câu trả lời có thể ít phức tạp hơn), đây là cách cuối cùng tôi đã giải quyết nó.

(a) Tôi đã tra cứu cài đặt matplotlib mặc định của ipython trong C:\Python27\Lib\site-packages\IPython\zmq\pylab\backend_inline.py (xem câu trả lời của Matt).

(b) và ghi đè lên chúng với các giá trị như quy định trong phiên bản thiết bị đầu cuối (tôi đã sử dụng print mpl.rcParams['figure.figsize'] vv để tìm hiểu) bằng cách chèn đoạn mã sau vào kịch bản của tôi:

import matplotlib as mpl 

#To make sure we have always the same matplotlib settings 
#(the ones in comments are the ipython notebook settings) 

mpl.rcParams['figure.figsize']=(8.0,6.0) #(6.0,4.0) 
mpl.rcParams['font.size']=12    #10 
mpl.rcParams['savefig.dpi']=100    #72 
mpl.rcParams['figure.subplot.bottom']=.1 #.125 
+0

Lưu ý rằng bạn chỉ cần ghi đè cài đặt MPL thay vì ngăn IPython thay đổi chúng như Matt gợi ý. –

+0

@hans: có lẽ. Nhưng nó đạt được mục tiêu của câu hỏi của tôi: đảm bảo mọi thứ trông giống nhau. – Rabarberski

2

Kích thước phông chữ vấn đề là do sự khác biệt trong dpi. Tôi đoán kích thước hơi khác nhau của hình (tính bằng pixel) cũng thay đổi vị trí "tốt nhất" cho chú giải.

Hình dpi mặc định được hiển thị là 80, trong khi savefig mặc định là 100. Điều này có nghĩa là theo mặc định, số liệu matplotlib sẽ hơi khác khi được lưu so với nội dung được hiển thị trên màn hình.

Tôi không biết chắc chắn, nhưng tôi đoán rằng sổ ghi chép ipython đặt dpi thành một cái gì đó khác hơn 100 (rất có thể là 80) và sử dụng khi lưu số liệu.

Hãy thử thực hiện savefig('filename.pdf', dpi=80) trong tập lệnh độc lập của bạn.

+0

Điều này dường như rất hứa hẹn, nhưng cho đến nay nó không giúp được gì. Và khi tôi làm 'print fig.get_dpi()' (trước 'savefig (...)' hoặc thiết lập nó, rõ ràng) cả Ipython và báo cáo terminal '80'. Tôi sẽ cố gắng tìm ra ngày mai nếu thực sự dpi không phải là một cách khác để đổ lỗi. (Hiện tại, tôi đã cập nhật mã của mình để cho phép định vị chú giải mà tôi muốn cho biểu đồ đơn này) – Rabarberski

+0

Vâng, in 'fig.get_dpi()' trước và sau khi 'savefig' sẽ không trợ giúp, vì' savefig' không chạm vào 'fig.dpi' ở tất cả (và hoàn toàn bỏ qua nó, thực sự). Chúc may mắn, ở mức nào! Tôi vẫn đoán đó là một vấn đề DPI, nhưng giải pháp chính xác có thể phức tạp hơn một chút. –

7

Để hoàn thành Joe câu trả lời, các inlinebackend (IPython/kernel/zmq/pylab/backend_inline.py) có một số thông số matplotlib mặc định:

# The typical default figure size is too large for inline use, 
# so we shrink the figure size to 6x4, and tweak fonts to 
# make that fit. 
rc = Dict({'figure.figsize': (6.0,4.0), 
    # play nicely with white background in the Qt and notebook frontend 
    'figure.facecolor': 'white', 
    'figure.edgecolor': 'white', 
    # 12pt labels get cutoff on 6x4 logplots, so use 10pt. 
    'font.size': 10, 
    # 72 dpi matches SVG/qtconsole 
    # this only affects PNG export, as SVG has no dpi setting 
    'savefig.dpi': 72, 
    # 10pt still needs a little more room on the xlabel: 
    'figure.subplot.bottom' : .125 
    }, config=True, 
    help="""Subset of matplotlib rcParams that should be different for the 
    inline backend.""" 
) 

Vì đây là không rõ ràng cho mọi người, bạn có thể đặt nó trong cấu hình thông qua c.InlineBackend.rc.

[Chỉnh sửa] thông tin chính xác về khả năng định cấu hình.

IPython có đặc thù là hầu hết các lớp đều có các thuộc tính có thể định cấu hình các giá trị mặc định.Những thường refered như Configurable (chữ hoa C), những người sở hữu có thể dễ dàng được nhận ra trong các mã như họ đang tuyên bố như vậy trước khi __init__:

property = A_Type(<default_value>, config=True , help="a string") 

Bạn có thể ghi đè lên các thuộc tính trong các tập tin cấu hình IPython (cái nào phụ thuộc vào những gì bạn muốn làm) bằng cách làm

c.ClassName.propertie_name = value 

đây vì nó là một dict bạn có thể làm

#put your favorite matplotlib config here. 
c.InlineBackend.rc = {'figure.facecolor': 'black'} 

I đoán một dict trống sẽ cho phép nội tuyến phụ trợ để sử dụng mặc định matplotlib.

+0

Tôi không chắc chắn nên làm gì với 'c.InlineBackend.rc' mà bạn đã đề xuất; Tôi đặt nó vào một tập tin 'matplotlibrc', nhưng điều đó đã cho tôi một 'lỗi dòng bất hợp pháp'. Tuy nhiên, tôi đã có được hai đầu ra giống hệt nhau bằng cách tra cứu các thiết lập trong tệp 'C: \ Python27 \ Lib \ site-packages \ IPython \ zmq \ pylab \ backend_inline.py' (mặt/edgecolors không có trong đó) tập tin) và chèn chúng vào đầu kịch bản python của tôi bằng cách sử dụng 'mpl.rcParams ['figure.figsize'] = (6.0.4.0)' và 'mpl.rcParams ['font.size'] = 10' vv. tốt ý tưởng để chỉnh sửa câu trả lời của bạn để bao gồm giải pháp này (tức là, bằng cách sử dụng rcParams)? – Rabarberski

+0

Đã thêm một số bình luận về cấu hình rc và IPython. Nhưng nó là một chủ đề phức tạp đến mức tôi không thể đi sâu vào chi tiết về cách nó hoạt động. Đó là loại giá trị mặc định ghi đè lên matplotlib rc trong một số trường hợp .... – Matt

+0

Tôi không hiểu tại sao bạn nói nó quá phức tạp. Tôi đã thêm giải pháp cuối cùng của tôi như là một câu trả lời riêng biệt ... – Rabarberski