Графики matplotlib выглядят как R по умолчанию?
Есть ли способ заставить matplotlib
вести себя одинаково с R или почти как R в плане построения значений по умолчанию? Например, R обрабатывает свои оси совсем иначе, чем matplotlib
. Следующая гистограмма
![enter image description here]()
имеет "плавающие оси" с наружными клещами, так что внутренних тиков нет (в отличие от matplotlib
), а оси не пересекаются "рядом" с началом. Кроме того, гистограмма может "перетекать" в значения, которые не отмечены галочкой - например, ось х заканчивается на 3, но гистограммы немного выходят за ее пределы. Как это может быть достигнуто автоматически для всех гистограмм в matplotlib
?
Связанный вопрос: графики рассеяния и линейные графики имеют разные настройки осей по умолчанию в R, например:
![enter image description here]()
Там нет внутренних клещей снова, и клещи обращены наружу. Кроме того, тики начинаются немного после точки начала (где оси y и x пересекаются в левом нижнем углу осей), а тики заканчиваются немного до окончания осей. Таким образом, метки с наименьшим типом оси x и самым низким типом оси y не могут пересекаться, потому что между ними есть пространство, и это дает очень элегантный вид. Обратите внимание, что также значительно больше места между осями ticklabels и самими клещами.
Кроме того, по умолчанию на немаркированных осях x или y нет меток, что означает, что ось y слева, параллельная отмеченной оси y справа, не имеет тиков, и то же самое для x -axis, снова удаляя беспорядок с графиков.
Есть ли способ сделать matplotlib похожим на это? И вообще посмотреть по умолчанию столько же, сколько по умолчанию R-графики? Мне нравится matplotlib
много, но я думаю, что поведение по умолчанию в режиме по умолчанию/по-оф-оф-оф-лайн действительно прав, и его настройки по умолчанию редко приводят к перекрытию меток ярлыков, беспорядочных или хард-данных, поэтому мне бы хотелось, чтобы значения по умолчанию как можно больше.
Ответы
Ответ 1
Редактировать 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 : out
и ytick.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]()
Так что да. Это не совсем тривиально, но вы можете приблизиться.
Ответ 2
matplotlib >= 1.4 suports стили (и встроен стиль 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]()
Ответ 3
#
#
#
#
#
#
EDIT 10/14/2013:
Для информации ggplot теперь реализован для python (построен на matplotlib).
Смотрите blog или перейдите непосредственно к github страница проекта для получения дополнительной информации и примеров.
#
#
#
#
#
#
Насколько мне известно, в matplotlib нет встроенного решения, которое напрямую придаст вашим фигурам аналогичный вид, чем те, что сделаны с R.
Некоторые пакеты, такие как mpltools, добавляет поддержку стилей с использованием параметров rc Matplotlibs и могут помочь вам получить внешний вид ggplot (см. стиль ggplot для примера).
Однако, поскольку все может быть изменено в 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 баллов (взято из this пример на веб-сайте 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
Например, код и два графика ниже показывают вам вывод по умолчанию из 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, но я не уверен, что сейчас есть другие варианты.
Ответ 4
Я бы посмотрел Bokeh, целью которого является "обеспечить убедительный эквивалент Pggon для ggplot в R". Пример здесь
EDIT: также проверьте Seaborn, который пытается воспроизвести визуальный стиль и синтаксис ggplot2.
Ответ 5
Вот сообщение в блоге, которое может вас заинтересовать:
График для Pandas GSoC2012
http://pandasplotting.blogspot.com/
Решено попробовать реализовать интерфейс построения графического интерфейса ggplot2... Не уверен, сколько функций ggplot2 будет реализовано...
Автор искал Pandas и построил то, что выглядит довольно много грамматики ggplot2 в 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())
Форк Pandas находится здесь: 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
Я думал, что это действительно круто, но я не могу понять, поддерживается ли этот проект или нет. Последняя фиксация была недавно.
Ответ 6
Настройка шипов в matplotlibrc объясняет, почему невозможно просто редактировать значения по умолчанию Matplotlib для создания гистограмм R-стиля. Для участков рассеяния,
R-образный буфер данных в matplotlib и В matplotlib, как вы рисуете тики оси R-стиля, указывающие на внешнюю сторону axes? показывают некоторые значения по умолчанию, которые можно изменить, чтобы дать больше 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
Ответ 7
import matplotlib.pyplot as plt
plt.style.use('ggplot')
сделайте что-нибудь здесь, и наслаждайтесь им