ves*_*and 7 python monkeypatching matplotlib pandas
问题:
我正在尝试掌握猴子修补的概念,同时创建一个函数来生成完美的时间序列图.如何在pandas pandas.DataFrame.plot()中包含以下matplotlib功能?
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
Run Code Online (Sandbox Code Playgroud)
complete code at the end of the question
细节:
我认为默认设置df.plot()非常简洁,特别是如果你正在运行一个黑暗主题的Jupyter笔记本,比如来自dunovank的chesterish:
我想尽可能多地使用它来处理我的数据分析工作流程,但我真的想要删除框架(或者所谓的刺)这样:
可以说,这是一个完美的时间序列图.但是df.plot()没有内置的论据.最接近的似乎是grid = False,但这会在同一次运行中夺走整个网格:
我试过的
我知道我可以将spine片段包装在一个函数中,df.plot()所以我最终得到了这个:
小片1:
def plotPerfect(df, spline):
ax = df.plot()
if not spline:
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
return(ax)
plotPerfect(df = df, spline = False)
Run Code Online (Sandbox Code Playgroud)
输出1:
但就未来修正的灵活性和可读性而言,这是"最好的"方式吗?如果我们谈论数百个情节,甚至是关于执行时间最快的?
我知道如何获得df.plot() 消息来源,但是那里的一切让我感到困惑.那么,如何做我包括这些设置df.plot?也许包裹的函数方法和猴子修补一样好?
包含完整代码和示例数据的代码段:
要重现100%的示例,请将其粘贴到Jupyter Notebook单元格中并chesterish theme激活:
# imports
import pandas as pd
import numpy as np
from jupyterthemes import jtplot
# Sample data
np.random.seed(123)
rows = 50
dfx = pd.DataFrame(np.random.randint(90,110,size=(rows, 1)), columns=['Variable Y'])
dfy = pd.DataFrame(np.random.randint(25,68,size=(rows, 1)), columns=[' Variable X'])
df = pd.concat([dfx,dfy], axis = 1)
jtplot.style()
# Plot with default settings
df.plot()
# Wrap df.plot() and matplotlib spine in a function
def plotPerfect(df, spline):
ax = df.plot()
if not spline:
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
return(ax)
# Plot the perfect time-series plot
plotPerfect(df = df, spline = False)
Run Code Online (Sandbox Code Playgroud)
这似乎是一个xy问题。
该问题要求猴子修补 pandas 绘图功能以添加附加功能。pandas.plotting._core.plot_frame在这种情况下,可以通过用其自定义版本替换该函数来完成。
import pandas as pd
import pandas.plotting._core
orginal = pandas.plotting._core.plot_frame
def myplot(*args, **kwargs):
spline = kwargs.pop("spline", True)
ax = orginal(*args, **kwargs)
ax.set_frame_on(spline)
ax.grid(not spline)
ax.tick_params(left=spline, bottom=spline)
return ax
pandas.plotting._core.plot_frame = myplot
Run Code Online (Sandbox Code Playgroud)
然后将其用作
df = pd.DataFrame([[0.1, 0.1], [0.9, 0.9]]).set_index(0)
df.plot() ## Normal Plot
df.plot(spline=False) ## "Despined" Plot
Run Code Online (Sandbox Code Playgroud)
请注意,如果在 Jupyter Notebook 中,带有猴子补丁的单元不能运行多次,否则最终会导致递归。
上面的内容对于改变情节风格来说是相当过分的。人们应该使用matplotlib 的样式选项。
mystyle = {"axes.spines.left" : False,
"axes.spines.right" : False,
"axes.spines.bottom" : False,
"axes.spines.top" : False,
"axes.grid" : True,
"xtick.bottom" : False,
"ytick.left" : False,}
Run Code Online (Sandbox Code Playgroud)
然后要将其应用于笔记本中的某些绘图,请使用plt.style.context管理器,
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame([[0.1, 0.1], [0.9, 0.9]]).set_index(0)
df.plot() ## Normal Plot
with plt.style.context(mystyle):
df.plot() ## "Despined" Plot
Run Code Online (Sandbox Code Playgroud)
或者,如果您想全局应用此样式,请更新rcParams.
plt.rcParams.update(mystyle)
Run Code Online (Sandbox Code Playgroud)