2010-03-09 19 views
6

Tôi đang thử nghiệm với matplotlib tại thời điểm này. Một thời gian trước, tôi đã sử dụng mã VBA Excel để tạo ra các hình ảnh như hình đính kèm.Làm cách nào để tạo các biểu đồ kiểu sinh viên bằng matplotlib?

Bạn sẽ nhận thấy nó không được trình bày theo phong cách khoa học/nghiên cứu mà đúng hơn là được sản xuất bởi một học sinh trên giấy vẽ - với ba kiểu lưới khác nhau.

Có cách nào khá đơn giản để đạt được loại điều này với matplotlib không?

alt text

Trả lời

8

Có, bạn có thể sử dụng spines cho việc này.

import matplotlib.pyplot as plt 
from matplotlib.ticker import MultipleLocator, FormatStrFormatter 
import numpy as np 

fig = plt.figure(1) 
ax = fig.add_subplot(111) 

# set up axis 
ax.spines['left'].set_position('zero') 
ax.spines['right'].set_color('none') 
ax.spines['bottom'].set_position('zero') 
ax.spines['top'].set_color('none') 
ax.xaxis.set_ticks_position('bottom') 
ax.yaxis.set_ticks_position('left') 

# draw curve 
x = np.arange(-2.5,2.5,0.01) 
line, = ax.plot(x, x**2) 

#set bounds 
ax.set_ybound(-1,7) 

# create grid 
#ax.xaxis.set_major_locator(MultipleLocator(1)) 
#ax.xaxis.set_minor_locator(MultipleLocator(0.2)) 
#ax.yaxis.set_major_locator(MultipleLocator(1)) 
#ax.yaxis.set_minor_locator(MultipleLocator(0.2)) 
#ax.xaxis.grid(True,'minor') 
#ax.yaxis.grid(True,'minor') 
#ax.xaxis.grid(True,'major',linewidth=2) 
#ax.yaxis.grid(True,'major',linewidth=2) 

#adjust grid on the 2s 
#for idx,loc in enumerate(ax.xaxis.get_majorticklocs()): 
    #if loc !=0 and loc % 2 == 0: ax.get_xgridlines()[idx].set_c('r') 
#for idx,loc in enumerate(ax.yaxis.get_majorticklocs()): 
    #if loc !=0 and loc % 2 == 0: ax.get_ygridlines()[idx].set_c('r') 

## THIS IS THE EDIT 
ax.xaxis.set_minor_locator(MultipleLocator(0.2)) 
ax.yaxis.set_minor_locator(MultipleLocator(0.2)) 
ax.xaxis.grid(True,'minor',linewidth=2) 
ax.yaxis.grid(True,'minor',linewidth=2) 

minor_grid_lines = [tick.gridline for tick in ax.xaxis.get_minor_ticks()] 
for idx,loc in enumerate(ax.xaxis.get_minorticklocs()): 
    if loc % 2.0 == 0: minor_grid_lines[idx].set_c('r') 
    elif loc % 1.0 == 0: minor_grid_lines[idx].set_c('g') 
    else: minor_grid_lines[idx].set_c('b') 

plt.show() 

alt text http://i42.tinypic.com/a1pcw3.png

+0

này tuyệt vời !!! Điều đó có vẻ chỉ là những gì tôi đã sau. Rất rất cảm ơn! – Geddes

+0

Câu hỏi cuối cùng của tôi là: có cách nào để có được ba kiểu đường lưới khác nhau không? Tôi muốn có một phong cách cho * 0.2, một phong cách khác cho * 1 và một phong cách khác cho * 2 (như trong đồ thị giấy). Điều này có vẻ khó khăn như matplotlib dường như chỉ áp dụng các ve lớn/nhỏ. Cảm ơn một lần nữa! – Geddes

+0

@Geddes, xem các chỉnh sửa ở trên. Tôi nghĩ cách dễ nhất là chỉ điều chỉnh các đường lưới dựa trên vị trí của chúng (tức là trên bội số của 2). – Mark

1

Chỉ cần một suy nghĩ - Tôi cũng đã cố gắng làm tất cả với các đường lưới nhỏ (ngoài việc gì khác nó sẽ giúp hiểu biết của tôi), nhưng nó không liệt kê đúng cách, không có nghi ngờ do get_minorticklocs và ax.get_xgridlines. Xin lỗi, và cảm ơn trước ...

Geddes

import matplotlib.pyplot as plt 
from matplotlib.ticker import MultipleLocator, FormatStrFormatter 
import numpy as np 

fig = plt.figure(1) 
ax = fig.add_subplot(111) 

# set up axis 
ax.spines['left'].set_position('zero') 
ax.spines['right'].set_color('none') 
ax.spines['bottom'].set_position('zero') 
ax.spines['top'].set_color('none') 
ax.xaxis.set_ticks_position('bottom') 
ax.yaxis.set_ticks_position('left') 

# draw curve 
x = np.arange(-2.5,2.5,0.01) 
line, = ax.plot(x, x**2) 

#set bounds 
ax.set_ybound(-1,7) 

# create grid 
ax.xaxis.set_minor_locator(MultipleLocator(0.2)) 
ax.yaxis.set_minor_locator(MultipleLocator(0.2)) 
ax.xaxis.grid(True,'minor',linewidth=2) 
ax.yaxis.grid(True,'minor',linewidth=2) 

#adjust grid on the 2s 
for idx,loc in enumerate(ax.xaxis.get_minorticklocs()): 
    if loc % 2 == 0: ax.get_xgridlines()[idx].set_color('r') 
    if loc % 1 == 0: ax.get_xgridlines()[idx].set_color('g') 
    if loc % 0.2 == 0: ax.get_xgridlines()[idx].set_color('b') 

for idx,loc in enumerate(ax.yaxis.get_majorticklocs()): 
    if loc % 2 == 0: ax.get_ygridlines()[idx].set_c('b') 

plt.savefig('spines3.png',dpi=300) 
+0

@Geddes, rìu .get_xgridlines() chỉ trả lại các đường lưới chính. Xem chỉnh sửa cho câu trả lời của tôi ở trên. – Mark

+0

Tuyệt vời - cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn hôm nay Mark - Tôi biết tôi là khách hàng khó tính! Tất cả những điều ước tốt nhất của tôi, Geddes – Geddes

0

Đây là một phiên bản sửa đổi của câu trả lời được chấp nhận ở trên. Có lẽ ai đó sẽ tìm thấy hữu ích

import matplotlib.pyplot as plt 
from matplotlib.ticker import MultipleLocator, FormatStrFormatter 
import numpy as np 
from matplotlib.ticker import FormatStrFormatter 

_fontsize_legend = 10 
_fontsize = 15 

DP = 2 

fig = plt.figure(figsize=(12, 12), dpi=100, facecolor='w', edgecolor='k') 
##fig = plt.figure() 
fig.canvas.draw() 
ax = plt.gca() 

# set up axis 
ax.spines['left'].set_position('zero') 
ax.spines['right'].set_color('none') 
ax.spines['bottom'].set_position('zero') 
ax.spines['top'].set_color('none') 
ax.xaxis.set_ticks_position('bottom') 
ax.yaxis.set_ticks_position('left') 

# draw curve 
x = np.arange(-2.5,2.5,0.01) 
line, = ax.plot(x, x**2) 

#set bounds 
ax.set_ybound(-1,7) 

## THIS IS THE EDIT 
ax.xaxis.set_major_locator(MultipleLocator(1/4)) 
ax.yaxis.set_major_locator(MultipleLocator(1/4)) 
ax.xaxis.grid(True,'major',linewidth=2/DP,linestyle='-',color='#d7d7d7',zorder=0) 
ax.yaxis.grid(True,'major',linewidth=2/DP,linestyle='-',color='#d7d7d7') 

ax.xaxis.set_minor_locator(MultipleLocator((1/4)/5)) 
ax.yaxis.set_minor_locator(MultipleLocator((1/4)/5)) 
ax.xaxis.grid(True,'minor',linewidth=0.5/DP,linestyle='-',color='#d7d7d7') 
ax.yaxis.grid(True,'minor',linewidth=0.5/DP,linestyle='-',color='#d7d7d7') 

ax.set_axisbelow(True) 
ax.set_aspect('equal') 

##ax.axhline(linewidth=0) 
##ax.axvline(linewidth=0) 

ax.xaxis.set_major_formatter(FormatStrFormatter('%i')) 
xticks = ax.xaxis.get_major_ticks() 
for i,l in enumerate(xticks): 
    if not (i - 1) % 4 == 0: 
     xticks[i].label1.set_visible(False) 
    else: 
     xticks[i].label1.set_fontsize(_fontsize) 

ax.yaxis.set_major_formatter(FormatStrFormatter('%i')) 
yticks = ax.yaxis.get_major_ticks() 
for i,l in enumerate(yticks): 
    if not (i - 1) % 4 == 0: 
     yticks[i].label1.set_visible(False) 
    else: 
     yticks[i].label1.set_fontsize(_fontsize)  

figManager = plt.get_current_fig_manager() 
figManager.window.showMaximized() 
plt.show() 

This is how this sample looks [picture]

Các vấn đề liên quan