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

时间:2013-01-15 23:45:54

标签: python r matplotlib plot pandas

在绘制默认值方面,有没有办法让matplotlib与R相同,或者几乎像R一样?例如,R对其轴的处理方式与matplotlib完全不同。以下直方图 enter image description here

具有向外刻度的“浮动轴”,因此没有内部刻度(与matplotlib不同)并且轴不会“接近”原点。此外,直方图可以“溢出”到没有标记的值 - 例如x轴以3结束,但直方图略微超出它。如何在matplotlib

中自动实现所有直方图

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

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

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

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

8 个答案:

答案 0 :(得分:44)

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

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

答案 1 :(得分:32)

matplotlib> = 1.4支持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

答案 2 :(得分:28)

# # # # # #

编辑2013年10月14日: 有关信息,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)

编辑:对于非接触性刺,请参阅下面的函数,该函数会引起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图一模一样,但我不确定现在还有其他选项。

答案 3 :(得分:10)

我会查看Bokeh,其目的是“在R中提供令人信服的Python等效ggplot”。示例here

编辑:同时查看Seaborn,它会尝试重现ggplot2的视觉风格和语法。

答案 4 :(得分:4)

以下是您可能有兴趣阅读的博文:

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

pandas fork在这里:https://github.com/orbitfold/pandas

看起来像代码的肉,使受R影响的图形位于名为rplot.py的文件中,可以在回购的分支中找到。

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

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

答案 5 :(得分:2)

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外观。假设您使用hist()Axes实例上调用了facecolor='none',以下函数可以很好地模仿R的直方图样式。

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

答案 6 :(得分:1)

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

答案 7 :(得分:0)

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

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