【问题标题】:How can I produce student-style graphs using matplotlib?如何使用 matplotlib 生成学生风格的图表?
【发布时间】:2011-01-25 11:17:35
【问题描述】:

我目前正在尝试使用 matplotlib。前段时间,我使用 Excel VBA 代码生成图像,如附件。

您会注意到它不是以科学/研究风格呈现的,而是由学生在方格纸上制作的 - 具有三种不同的网格线样式。

有没有一种相当直接的方法可以用 matplotlib 实现这种事情?

【问题讨论】:

    标签: python matplotlib wxpython


    【解决方案1】:

    这是上述已接受答案的修改版本。 也许有人会觉得这很有帮助

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

    【讨论】:

      【解决方案2】:

      是的,您可以为此使用spines

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

      【讨论】:

      • 我的最后一个问题是:有没有办法获得三种不同的网格线样式?我想要*0.2 的一种样式,*1 的另一种样式,*2 的另一种样式(如方格纸)。这似乎很困难,因为 matplotlib 似乎只强加了主要/次要刻度。再次感谢!
      • @Geddes,见上面的编辑。我认为最简单的方法是根据网格线的位置(即 2 的倍数)调整网格线。
      • 再次感谢马克。我现在必须解决这个问题 - 一些非常先进的东西正在发生!一切顺利。
      【解决方案3】:

      只是另一个想法 - 我也尝试使用次要网格线来完成所有操作(除了有助于我理解的任何其他内容),但它没有正确枚举,毫无疑问是由于 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)
      

      【讨论】:

      • @Geddes, ax.get_xgridlines() 只返回主要的网格线。请参阅上面对我的答案的修改。
      • 太棒了-非常感谢您今天提供的所有帮助马克-我知道我是一个苛刻的客户!我所有最良好的祝愿,Geddes
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-01
      • 2014-11-07
      • 2013-05-09
      相关资源
      最近更新 更多