58 votes

faire en sorte que les graphiques de matplotlib ressemblent à ceux de R par défaut ?

Y a-t-il un moyen de faire matplotlib se comporte-t-il de la même manière que R, ou presque, en termes de valeurs par défaut pour le traçage ? Par exemple, R traite ses axes de manière assez différente de celle de R. matplotlib . L'histogramme suivant enter image description here

a des "axes flottants" avec des ticks extérieurs, de telle sorte qu'il n'y a pas de ticks intérieurs (contrairement à matplotlib ) et les axes ne se croisent pas "près" de l'origine. De même, l'histogramme peut "déborder" sur des valeurs qui ne sont pas marquées par la coche - par exemple, l'axe des x se termine à 3 mais l'histogramme s'étend légèrement au-delà. Comment cela peut-il être réalisé automatiquement pour tous les histogrammes dans la base de données de l'UE ? matplotlib ?

Question connexe : les diagrammes de dispersion et les diagrammes linéaires ont des paramètres d'axes par défaut différents dans R, par exemple : enter image description here

Il n'y a plus de tics internes et les tics sont orientés vers l'extérieur. De plus, les tics commencent légèrement après le point d'origine (où les axes y et x se croisent en bas à gauche des axes) et les tics se terminent légèrement avant la fin des axes. De cette façon, les étiquettes du tic-tac le plus bas de l'axe des x et du tic-tac le plus bas de l'axe des y ne peuvent pas vraiment se croiser, car il y a un espace entre elles et cela donne aux graphiques un aspect propre et élégant. Notez qu'il y a également beaucoup plus d'espace entre les étiquettes des axes et les ticks eux-mêmes.

De plus, par défaut, il n'y a pas de tics sur les axes x ou y non étiquetés, ce qui signifie que l'axe y de gauche qui est parallèle à l'axe y étiqueté de droite n'a pas de tics, et il en va de même pour l'axe x, ce qui permet d'éliminer le désordre des graphiques.

Existe-t-il un moyen de faire en sorte que matplotlib ressemble à cela ? Et en général de ressembler par défaut à des tracés R ? J'aime matplotlib mais je pense que les paramètres par défaut de R / le comportement de traçage prêt à l'emploi ont vraiment bien fait les choses et ses paramètres par défaut conduisent rarement à des étiquettes de tic-tac qui se chevauchent, à un encombrement ou à des données écrasées, donc j'aimerais que les paramètres par défaut soient aussi semblables que possible.

44voto

Paul H Points 5612

Cet article de blog est le meilleur que j'ai vu jusqu'à présent. http://messymind.net/making-matplotlib-look-like-ggplot/

Il ne se concentre pas sur les tracés standard de R, comme c'est le cas dans la plupart des exemples de type "débutant". Il tente plutôt d'imiter le style de ggplot2, qui semble être presque universellement reconnu comme élégant et bien conçu.

Pour obtenir les épines d'axe comme vous le voyez dans le graphique en barres, essayez de suivre l'un des premiers exemples ici : http://www.loria.fr/~rougier/coding/gallery/

Enfin, pour faire en sorte que les marques de l'axe pointent vers l'extérieur, vous pouvez éditer votre matplotlibrc fichiers à dire xtick.direction : out y ytick.direction : out .

En combinant ces concepts, on obtient quelque chose comme ceci :

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

La position des épines peut être spécifiée de plusieurs façons. Si vous exécutez le code ci-dessus en IPython, vous pouvez alors faire axes.spines['bottom'].set_position? pour voir toutes vos options.

R-style bar plot in python

Donc oui. Ce n'est pas exactement trivial, mais vous pouvez vous en approcher.

33voto

bmu Points 7109

Supporte matplotlib >= 1.4 styles (et ggplot-style est intégré) :

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

28voto

gcalmettes Points 2391

# # # # # #

EDIT 10/14/2013 : Pour information, ggplot a maintenant été implémenté pour python (construit sur matplotlib).

Voir ceci blog ou aller directement à la page github du projet pour plus d'informations et d'exemples.

# # # # # #

A ma connaissance, il n'y a pas de solution intégrée dans matplotlib qui donnera directement à vos chiffres un aspect similaire à ceux réalisés avec R.

Certains paquets, comme mpltools ajoute la prise en charge des feuilles de style utilisant les paramètres rc de Matplotlib, et peut vous aider à obtenir un aspect ggplot (voir le fichier Style ggplot pour un exemple).

Cependant, comme tout peut être modifié dans matplotlib, il pourrait être plus facile pour vous de développer directement vos propres fonctions pour obtenir exactement ce que vous voulez. À titre d'exemple, voici un extrait qui vous permettra de personnaliser facilement les axes de n'importe quel graphique 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)

EDITAR: pour les épines qui ne se touchent pas, voir la fonction ci-dessous qui induit un déplacement de 10 pts des épines (tiré de cet exemple sur le site web de 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

Par exemple, le code et les deux graphiques ci-dessous vous montrent la sortie par défaut de matplotib (à gauche), et la sortie lorsque les fonctions sont appelées (à droite) :

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

Bien sûr, il vous faudra du temps pour comprendre quels paramètres doivent être modifiés dans matplotlib pour que vos graphiques ressemblent exactement à ceux de R, mais je ne suis pas sûr qu'il y ait d'autres options pour le moment.

10voto

Brian Keegan Points 561

Je vérifierais Bokeh qui vise à "fournir un équivalent Python convaincant de ggplot dans R". Exemple aquí

EDIT : Vérifiez également Seaborn qui tente de reproduire le style visuel et la syntaxe de ggplot2.

4voto

hernamesbarbara Points 1229

Voici un article de blog que vous pourriez être intéressé à lire :

Traçage pour Pandas GSoC2012

http://pandasplotting.blogspot.com/

J'ai décidé d'essayer d'implémenter une interface de traçage de type ggplot2... Je ne suis pas encore sûr de la quantité de fonctionnalités de ggplot2 à implémenter...

L'auteur a forqué pandas et a construit ce qui semble être une bonne partie de la grammaire de style ggplot2 pour pandas.

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

La fourchette des pandas est ici : https://github.com/orbitfold/pandas

Il semble que la majeure partie du code pour faire les graphiques influencés par R est dans un fichier appelé rplot.py qui se trouve dans une branche du 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.
    """

Lien vers la branche :

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

Je pensais que c'était vraiment cool, mais je n'arrive pas à savoir si ce projet est maintenu ou non. Le dernier commit date d'il y a un moment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X