Python 如何使用matplotlib生成学生风格的图形?

Python 如何使用matplotlib生成学生风格的图形?,python,matplotlib,wxpython,Python,Matplotlib,Wxpython,我现在正在试验matplotlib。不久前,我使用Excel VBA代码生成图像,如所附图像 你会注意到,它不是以科学/研究的方式呈现的,而是像是由一名在校学生用三种不同的网格线样式在图表纸上绘制的 使用matplotlib是否有一种相当简单的方法来实现这类功能 是的,您可以使用它 import matplotlib.pyplot as plt from matplotlib.ticker import MultipleLocator, FormatStrFormatter import num

我现在正在试验matplotlib。不久前,我使用Excel VBA代码生成图像,如所附图像

你会注意到,它不是以科学/研究的方式呈现的,而是像是由一名在校学生用三种不同的网格线样式在图表纸上绘制的

使用matplotlib是否有一种相当简单的方法来实现这类功能

是的,您可以使用它

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()

这只是另一个想法——我也尝试过使用次要网格线(除了有助于我理解的其他内容外),但由于get_minorticklocs和ax.get_xgridlines,它没有正确枚举。对不起,先谢谢你

格迪斯

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)

这是上述公认答案的修改版本。 也许有人会觉得这很有用

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()

我的最后一个问题是:有没有办法获得三种不同的网格线样式?我想要一个样式用于*0.2,另一个样式用于*1,还有一个样式用于*2(如在图纸中)。这似乎很困难,因为matplotlib似乎只施加主要/次要刻度。再次感谢@Geddes,请参见上面的编辑。我认为最简单的方法是根据网格线的位置(即2的倍数)调整网格线。再次感谢Mark。我现在得想一想了——一些非常先进的东西正在发生!一切都好。@Geddes,ax.getxgridlines()只返回主网格线。请参阅以上对我答案的编辑。太棒了-非常感谢您今天的帮助Mark-我知道我是一个要求很高的客户!祝你一切顺利,格迪斯