Python 默认情况下使 matplotlib 图形看起来像 R?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14349055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:09:05  来源:igfitidea点击:

making matplotlib graphs look like R by default?

pythonrmatplotlibplotpandas

提问by

Is there a way to make matplotlibbehave identically to R, or almost like R, in terms of plotting defaults? For example R treats its axes pretty differently from matplotlib. The following histogram enter image description here

matplotlib在绘制默认值方面,有没有办法使行为与 R 相同或几乎与 R 相同?例如,R 对待它的轴与matplotlib. 下面的直方图 在此处输入图片说明

has "floating axes" with outward ticks, such that there are no inner ticks (unlike matplotlib) and the axes do not cross "near" the origin. Also, the histogram can "spillover" to values that are not marked by the tick - e.g. the x-axis ends at 3 but the histograms extends slightly beyond it. How can this be achieved automatically for all histograms in matplotlib?

具有带有向外刻度的“浮动轴”,因此没有内部刻度(与 不同matplotlib)并且轴不会“靠近”原点。此外,直方图可以“溢出”到没有被刻度标记的值——例如,x 轴在 3 处结束,但直方图稍微超出它。如何为 中的所有直方图自动实现这一点matplotlib

Related question: scatter plots and line plots have different default axes settings in R, for example: enter image description here

相关问题:散点图和线图在 R 中有不同的默认轴设置,例如: 在此处输入图片说明

There no inner ticks again and the ticks face outward. Also, the ticks start slightly after the origin point (where the y and x axes cross at the bottom left of the axes) and the ticks end slightly before the axes end. This way the labels of the lowest x-axis tick and lowest y-axis tick can't really cross, because there's a space between them and this gives the plots a very elegant clean look. Note that there's also considerably more space between the axes ticklabels and the ticks themselves.

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

Also, by default there are no ticks on the non-labeled x or y axes, meaning the y-axis on the left that is parallel to the labeled y-axis on the right has no ticks, and same for the x-axis, again removing clutter from the plots.

此外,默认情况下,未标记的 x 或 y 轴上没有刻度,这意味着与右侧标记的 y 轴平行的左侧 y 轴没有刻度,x 轴也是如此,再次从情节中消除混乱。

Is there a way to make matplotlib look like this? And in general to look by default as much as default R plots? I like matplotliba lot but I think the R defaults / out-of-the-box plotting behavior really have gotten things right and its default settings rarely lead to overlapping tick labels, clutter or squished data, so I would like the defaults to be as much like that as possible.

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

回答by Brian Keegan

I would check out Bokehwhich aims to "provide a compelling Python equivalent of ggplot in R". Example here

我会查看Bokeh,它旨在“提供一个引人注目的 Python 等效于 R 中的 ggplot”。示例在这里

EDIT: Also check out Seaborn, which attempts to reproduce the visual style and syntax of ggplot2.

编辑:另请查看Seaborn,它试图重现 ggplot2 的视觉风格和语法。

回答by Paul H

Edit 1 year later:

一年后编辑:

With seaborn, the example below becomes:

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

Pretty dang easy.

很简单。

Original post:

原帖:

This blog post is the best I've seen so far. http://messymind.net/making-matplotlib-look-like-ggplot/

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

It doesn't focus on your standard R plots like you see in most of the "getting started"-type examples. Instead it tries to emulate the style of ggplot2, which seems to be nearly universally heralded as stylish and well-designed.

它不像您在大多数“入门”类型的示例中看到的那样专注于您的标准 R 图。相反,它试图模仿 ggplot2 的风格,它似乎几乎被普遍认为是时尚和精心设计的。

To get the axis spines like you see the in bar plot, try to follow one of the first few examples here: http://www.loria.fr/~rougier/coding/gallery/

要获得像条形图中看到的轴脊,请尝试按照此处的前几个示例之一进行操作:http: //www.loria.fr/~rougier/coding/gallery/

Lastly, to get the axis tick marks pointing outward, you can edit your matplotlibrcfiles to say xtick.direction : outand ytick.direction : out.

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

Combining these concepts together we get something like this:

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

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

The position of the spines can be specified a number of ways. If you run the code above in IPython, you can then do axes.spines['bottom'].set_position?to see all of your options.

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

R-style bar plot in python

python中的R样式条形图

So yeah. It's not exactly trivial, but you can get close.

是的。这并不完全是微不足道的,但你可以接近。

回答by gcalmettes

# # # # # #

######

EDIT 10/14/2013: For information, ggplot has now been implemented for python (built on matplotlib).

编辑 2013 年 10 月 14 日:有关信息,ggplot 现在已为 Python 实现(基于 matplotlib)。

See this blogor go directly to the github pageof the project for more information and examples.

查看此博客或直接前往项目的github 页面获取更多信息和示例。

# # # # # #

######

To my knowledge, there is no built-in solution in matplotlib that will directly give to your figures a similar look than the ones made with R.

据我所知,matplotlib 中没有内置解决方案可以直接为您的图形提供与使用 R 制作的图形类似的外观。

Some packages, like mpltools, adds support for stylesheets using Matplotlib's rc-parameters, and can help you to obtain a ggplot look (see the ggplot stylefor an example).

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

However, since everything can be tweaked in matplotlib, it might be easier for you to directly develop your own functions to achieve exactly what you want. As an example, below is a snippet that will allow you to easily customize the axes of any matplotlib plot.

但是,由于所有内容都可以在 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:for non touching spines, see the function below which induces a 10 pts displacement of the spines (taken from this exampleon the matplotlib website).

编辑:对于非接触脊椎,请参阅下面的函数,该函数会导致脊椎发生 10 pts 位移(取自matplotlib 网站上的此示例)。

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

For example, the code and the two plots below show you the default output from matplotib (on the left), and the output when the functions are called (on the right):

例如,下面的代码和两个图显示了 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

图片

Of course, it will take time for you to figure out which parameters have to be tweaked in matplotlib to make your plots look exactly like the R ones, but I am not sure there are other options right now.

当然,您需要时间来确定必须在 matplotlib 中调整哪些参数才能使您的绘图看起来与 R 的绘图完全一样,但我不确定现在是否还有其他选项。

回答by hernamesbarbara

Here's a blog post you may be interested to read:

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

Plotting for Pandas GSoC2012

Pandas GSoC2012 绘图

http://pandasplotting.blogspot.com/

http://pandasplotting.blogspot.com/

Decided to try to implement a ggplot2 type plotting interface...Not yet sure how much of the ggplot2 functionality to implement...

决定尝试实现一个ggplot2类型的绘图接口...目前还不确定要实现多少ggplot2功能...

The author forked pandas and built what looks like quite a lot of ggplot2-style grammar for pandas.

作者对 Pandas 进行了分叉,并为 Pandas 构建了很多看起来像 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())

The pandas fork is here: https://github.com/orbitfold/pandas

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

Seems like meat of the code to make the R-influenced graphics is in a file called rplot.pywhich can be found in a branch in the repo.

似乎制作受 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.
    """

Link to the branch:

分行链接:

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

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

I thought this was really cool, but I can't figure out if this project is being maintained or not. The last commit was a while ago.

我觉得这真的很酷,但我不知道这个项目是否正在维护。最后一次提交是在一段时间之前。

回答by JaminSore

Setting spines in matplotlibrcexplains why it is not possible to simply edit Matplotlib defaults to produce R-style histograms. For scatter plots, R style data-axis buffer in matplotliband In matplotlib, how do you draw R-style axis ticks that point outward from the axes?show some defaults that can be changed to give a more R-ish look. Building off some of the other answers, the following function does a decent job of mimicking R's histogram style, assuming you've called hist()on your Axesinstance with facecolor='none'.

在 matplotlibrc 中设置脊解释了为什么不能简单地编辑 Matplotlib 默认值来生成 R 样式的直方图。对于散点图, matplotlib 中的 R 样式数据轴缓冲区matplotlib 中,如何绘制从轴向外指向的 R 样式轴刻度?显示一些可以更改的默认值,以提供更 R-ish 的外观。建立了一些其他的答案,下面的函数模仿的r直方图风格的一份体面的工作,假设你叫hist()上你的Axes处理实例facecolor='none'

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

回答by bmu

matplotlib >= 1.4 suports styles(and ggplot-style is build in):

matplotlib >= 1.4 支持样式(并且内置了 ggplot 样式):

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

在此处输入图片说明

回答by afternone

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

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

do something plot here, and enjoy it

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

回答by altroware

The Seabornvisualisation library can do that. For example, to reproduce the style of the R histogram use:

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

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

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

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

enter image description here

在此处输入图片说明

To reproduce the style of the R scatter plot use:

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

sns.set_style("ticks")

as shown in https://seaborn.pydata.org/tutorial/aesthetics.html#seaborn-figure-styles

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

enter image description here

在此处输入图片说明