首页 文章

使matplotlib图形默认看起来像R?

提问于
浏览
58

在绘制默认值方面,有没有办法使 matplotlib 的行为与R相同,或者几乎与R相同?例如,R对待它的轴与 matplotlib 完全不同 . 以下直方图
enter image description here

具有向外刻度的"floating axes",因此没有内部刻度(与 matplotlib 不同)并且轴不与原点交叉"near" . 此外,直方图可以"spillover"到未标记的值 - 例如x轴以3结束,但直方图略微超出它 . 如何在 matplotlib 中自动实现所有直方图?

相关问题:散点图和线图在R中具有不同的默认轴设置,例如:
enter image description here

再没有内部蜱,蜱面朝外 . 此外,在原点(y轴和x轴在轴的左下方交叉)之后,刻度开始略微,并且在轴结束之前刻度稍微结束 . 这样,最低x轴刻度和最低y轴刻度的标签不能真正交叉,因为它们之间有一个空间,这使得绘图非常优雅干净 . 请注意,轴刻度标签和刻度本身之间的空间也相当大 .

此外,默认情况下,未标记的x或y轴上没有刻度,这意味着左侧的y轴与右侧标记的y轴平行,没有刻度,x轴相同,再次消除阴谋的混乱 .

有没有办法让matplotlib看起来像这样?一般来说,默认情况下看默认R图是多少?我很喜欢 matplotlib 但是我认为R默认/开箱即用的绘图行为确实让事情变得正确并且它的默认设置很少导致重叠的刻度标签,杂乱或压扁的数据,所以我希望默认值是尽可能多的那样 .

8 回答

  • 2

    编辑1年后:

    使用 seaborn ,以下示例变为:

    import numpy as np
    import matplotlib.pyplot as plt
    import seaborn
    seaborn.set(style='ticks')
    # Data to be represented
    X = np.random.randn(256)
    
    # Actual plotting
    fig = plt.figure(figsize=(8,6), dpi=72, facecolor="white")
    axes = plt.subplot(111)
    heights, positions, patches = axes.hist(X, color='white')
    seaborn.despine(ax=axes, offset=10, trim=True)
    fig.tight_layout()
    plt.show()
    

    相当容易 .

    原帖:

    这篇博文是迄今为止我见过的最好的 . http://messymind.net/making-matplotlib-look-like-ggplot/

    它并没有像你在大多数“入门”类型的例子中看到的那样关注你的标准R图 . 相反,它试图模仿ggplot2的风格,这似乎几乎普遍被称为时尚和精心设计 .

    要获得轴刺,就像您看到条形图一样,请尝试按照前面几个示例中的一个:http://www.loria.fr/~rougier/coding/gallery/

    最后,要使轴刻度标记指向外,您可以编辑 matplotlibrc 文件以说 xtick.direction : outytick.direction : out .

    将这些概念结合在一起我们得到这样的结论:

    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    # Data to be represented
    X = np.random.randn(256)
    
    # Actual plotting
    fig = plt.figure(figsize=(8,6), dpi=72, facecolor="white")
    axes = plt.subplot(111)
    heights, positions, patches = axes.hist(X, color='white')
    
    axes.spines['right'].set_color('none')
    axes.spines['top'].set_color('none')
    axes.xaxis.set_ticks_position('bottom')
    
    # was: axes.spines['bottom'].set_position(('data',1.1*X.min()))
    axes.spines['bottom'].set_position(('axes', -0.05))
    axes.yaxis.set_ticks_position('left')
    axes.spines['left'].set_position(('axes', -0.05))
    
    axes.set_xlim([np.floor(positions.min()), np.ceil(positions.max())])
    axes.set_ylim([0,70])
    axes.xaxis.grid(False)
    axes.yaxis.grid(False)
    fig.tight_layout()
    plt.show()
    

    可以通过多种方式指定脊柱的位置 . 如果您在IPython中运行上面的代码,那么您可以执行 axes.spines['bottom'].set_position? 以查看所有选项 .

    R-style bar plot in python

    是的 . 这不是一件容易的事,但你可以近距离接触 .

  • 32

    matplotlib> = 1.4 suports styles(并且内置了ggplot-style):

    In [1]: import matplotlib as mpl
    
    In [2]: import matplotlib.pyplot as plt
    
    In [3]: import numpy as np
    
    In [4]: mpl.style.available
    Out[4]: [u'dark_background', u'grayscale', u'ggplot']
    
    In [5]: mpl.style.use('ggplot')
    
    In [6]: plt.hist(np.random.randn(100000))
    Out[6]: 
    ...
    

    enter image description here

  • 43

    编辑10/14/2013:有关信息,ggplot现已实现为python(基于matplotlib构建) .

    有关更多信息和示例,请参阅此blog或直接转到项目的github page .

    据我所知,matplotlib中没有内置的解决方案,可以直接为您的人物提供与R制作的相似的外观 .

    一些软件包,如mpltools,使用Matplotlib的rc参数添加了对样式表的支持,并且可以帮助您获得ggplot外观(请参阅ggplot style以获取示例) .

    但是,由于所有内容都可以在matplotlib中进行调整,因此您可以更轻松地直接开发自己的函数来实现您想要的效果 . 例如,下面是一个片段,可以让您轻松自定义任何matplotlib图的轴 .

    def customaxis(ax, c_left='k', c_bottom='k', c_right='none', c_top='none',
                   lw=3, size=20, pad=8):
    
        for c_spine, spine in zip([c_left, c_bottom, c_right, c_top],
                                  ['left', 'bottom', 'right', 'top']):
            if c_spine != 'none':
                ax.spines[spine].set_color(c_spine)
                ax.spines[spine].set_linewidth(lw)
            else:
                ax.spines[spine].set_color('none')
        if (c_bottom == 'none') & (c_top == 'none'): # no bottom and no top
            ax.xaxis.set_ticks_position('none')
        elif (c_bottom != 'none') & (c_top != 'none'): # bottom and top
            ax.tick_params(axis='x', direction='out', width=lw, length=7,
                          color=c_bottom, labelsize=size, pad=pad)
        elif (c_bottom != 'none') & (c_top == 'none'): # bottom but not top
            ax.xaxis.set_ticks_position('bottom')
            ax.tick_params(axis='x', direction='out', width=lw, length=7,
                           color=c_bottom, labelsize=size, pad=pad)
        elif (c_bottom == 'none') & (c_top != 'none'): # no bottom but top
            ax.xaxis.set_ticks_position('top')
            ax.tick_params(axis='x', direction='out', width=lw, length=7,
                           color=c_top, labelsize=size, pad=pad)
        if (c_left == 'none') & (c_right == 'none'): # no left and no right
            ax.yaxis.set_ticks_position('none')
        elif (c_left != 'none') & (c_right != 'none'): # left and right
            ax.tick_params(axis='y', direction='out', width=lw, length=7,
                           color=c_left, labelsize=size, pad=pad)
        elif (c_left != 'none') & (c_right == 'none'): # left but not right
            ax.yaxis.set_ticks_position('left')
            ax.tick_params(axis='y', direction='out', width=lw, length=7,
                           color=c_left, labelsize=size, pad=pad)
        elif (c_left == 'none') & (c_right != 'none'): # no left but right
            ax.yaxis.set_ticks_position('right')
            ax.tick_params(axis='y', direction='out', width=lw, length=7,
                           color=c_right, labelsize=size, pad=pad)
    

    EDIT: 对于非接触性刺,请参阅下面的函数,该函数会引起10点位移的刺(取自matplotlib网站上的this example) .

    def adjust_spines(ax,spines):
        for loc, spine in ax.spines.items():
            if loc in spines:
                spine.set_position(('outward',10)) # outward by 10 points
                spine.set_smart_bounds(True)
            else:
                spine.set_color('none') # don't draw spine
    

    例如,下面的代码和两个图表显示了matplotib(左侧)的默认输出,以及调用函数时的输出(右侧):

    import numpy as np
    import matplotlib.pyplot as plt
    
    fig,(ax1,ax2) = plt.subplots(figsize=(8,5), ncols=2)
    ax1.plot(np.random.rand(20), np.random.rand(20), 'ok')
    ax2.plot(np.random.rand(20), np.random.rand(20), 'ok')
    
    customaxis(ax2) # remove top and right spines, ticks out
    adjust_spines(ax2, ['left', 'bottom']) # non touching spines
    
    plt.show()
    

    image

    当然,你需要时间来确定哪些参数必须在matplotlib中进行调整,以使你的图看起来与R图完全一样,但我不确定现在还有其他选项 .

  • 10

    我会查看Bokeh,其目标是"provide a compelling Python equivalent of ggplot in R" . 示例here

    编辑:还检查Seaborn,尝试重现ggplot2的视觉风格和语法 .

  • 0

    这是您可能有兴趣阅读的博客文章:

    Plotting for Pandas GSoC2012

    http://pandasplotting.blogspot.com/

    决定尝试实现ggplot2类型的绘图界面......还不确定要实现多少ggplot2功能......

    作者分配了大熊猫并为熊猫构建了很多ggplot2风格的语法 .

    Density Plots

    plot = rplot.RPlot(tips_data, x='total_bill', y='tip')
    plot.add(rplot.TrellisGrid(['sex', 'smoker']))
    plot.add(rplot.GeomHistogram())
    plot.render(plt.gcf())
    

    熊猫叉在这里:https://github.com/orbitfold/pandas

    看起来像代码的肉,使受R影响的图形在一个名为 rplot.py 的文件中,可以在repo的分支中找到 .

    class GeomScatter(Layer):
        """
        An efficient scatter plot, use this instead of GeomPoint for speed.
        """
    
    class GeomHistogram(Layer):
        """
        An efficient histogram, use this instead of GeomBar for speed.
        """
    

    链接到分支:

    https://github.com/orbitfold/pandas/blob/rplot/pandas/tools/rplot.py

    我认为这真的很酷,但我无法弄清楚这个项目是否得到维护 . 最后一次提交是不久前的 .

  • 4

    Setting spines in matplotlibrc解释了为什么不能简单地编辑Matplotlib默认值来生成R样式的直方图 . 对于散点图,R style data-axis buffer in matplotlibIn matplotlib, how do you draw R-style axis ticks that point outward from the axes?显示了一些可以更改的默认值,以提供更多的R-ish外观 . 通过 Build 一些其他答案,以下函数在 Axes 实例上用 facecolor='none' 模拟R 's histogram style, assuming you' ve,称为 hist() .

    def Rify(axes):
        '''
        Produce R-style Axes properties
        '''
        xticks = axes.get_xticks() 
        yticks = axes.get_yticks()
    
        #remove right and upper spines
        axes.spines['right'].set_color('none') 
        axes.spines['top'].set_color('none')
    
        #make the background transparent
        axes.set_axis_bgcolor('none')
    
        #allow space between bottom and left spines and Axes
        axes.spines['bottom'].set_position(('axes', -0.05))
        axes.spines['left'].set_position(('axes', -0.05))
    
        #allow plot to extend beyond spines
        axes.spines['bottom'].set_bounds(xticks[0], xticks[-2])
        axes.spines['left'].set_bounds(yticks[0], yticks[-2])
    
        #set tick parameters to be more R-like
        axes.tick_params(direction='out', top=False, right=False, length=10, pad=12, width=1, labelsize='medium')
    
        #set x and y ticks to include all but the last tick
        axes.set_xticks(xticks[:-1])
        axes.set_yticks(yticks[:-1])
    
        return axes
    
  • 0

    import matplotlib.pyplot as plt plt.style.use('ggplot')

    在这里做一些情节,并享受它

  • 27

    Seaborn可视化库可以做到这一点 . 例如,要重现R直方图的样式,请使用:

    sns.despine(offset=10, trim=True)
    

    https://seaborn.pydata.org/tutorial/aesthetics.html#removing-axes-spines

    enter image description here

    要重现R散点图的样式,请使用:

    sns.set_style("ticks")
    

    https://seaborn.pydata.org/tutorial/aesthetics.html#seaborn-figure-styles所示

    enter image description here

相关问题