python - MatplotlibDeprecationWarning:使用与先前轴相同的参数添加轴当前重用早期实例
问题描述
我正在编写一个脚本,该脚本根据节点的数量接收多个输入、解析数据并多次调用绘图函数。
问题是我多次调用我的绘图函数(见下面的代码),但我不知道如何解决这个问题。我看到了这个解决方案,但这不是我的情况(或者我不知道如何适用于我的情况)。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
sns.set(style="whitegrid")
fig, (ax1, ax2, ax3, ax4) = plt.subplots(nrows=1, ncols=4, figsize=(16, 4))
plt.tight_layout()
def plot_data(df, nodes):
global ax1, ax2, ax3, ax4
if nodes == 10:
plt.subplot(141)
ax1 = sns.kdeplot(df['Metric'], cumulative=True, legend=False)
ax1.set_ylabel('ECDF', fontsize = 16)
ax1.set_title('10 Nodes')
elif nodes == 20:
plt.subplot(142)
ax2 = sns.kdeplot(df['Metric'], cumulative=True, legend=False)
plt.setp(ax2.get_yticklabels(), visible=False)
ax2.set_title('20 Nodes')
elif nodes == 30:
plt.subplot(143)
ax3 = sns.kdeplot(df['Metric'], cumulative=True, legend=False)
plt.setp(ax3.get_yticklabels(), visible=False)
ax3.set_title('30 Nodes')
elif nodes == 40:
plt.subplot(144)
ax4 = sns.kdeplot(df['Metric'], cumulative=True, legend=False)
plt.setp(ax4.get_yticklabels(), visible=False)
ax4.set_title('40 Nodes')
df1 = pd.DataFrame({'Metric':np.random.randint(0, 15, 1000)})
df2 = pd.DataFrame({'Metric':np.random.randint(0, 15, 1000)})
df3 = pd.DataFrame({'Metric':np.random.randint(0, 15, 1000)})
nodes = [10, 20, 30, 40]
for i in range(4):
"""
In my real code, the DataFrames are calculated from reading CSV files.
Since that code would be too long, I'm using dummy data.
"""
plot_data(df1, nodes[i])
# I understand that this calls cause the warning,
# but I don't know how to solve it
plot_data(df2, nodes[i])
plot_data(df3, nodes[i])
plt.show()
解决方案
您需要删除plt.subplot(nnn)
. 正如警告所说,目前这样做将重用轴实例。但在未来的 matplotlib 版本中,这将创建一个新的轴实例。
解决方案是将您创建的轴作为参数传递给函数并使用以下ax=
参数seaborn.kdeplot
:
sns.set(style="whitegrid")
fig, axes = plt.subplots(nrows=1, ncols=4, figsize=(16, 4))
plt.tight_layout()
def plot_data(df, nodes, axes):
ax1, ax2, ax3, ax4 = axes
if nodes == 10:
sns.kdeplot(df['Metric'], cumulative=True, legend=False, ax=ax1)
ax1.set_ylabel('ECDF', fontsize = 16)
ax1.set_title('10 Nodes')
elif nodes == 20:
sns.kdeplot(df['Metric'], cumulative=True, legend=False, ax=ax2)
plt.setp(ax2.get_yticklabels(), visible=False)
ax2.set_title('20 Nodes')
elif nodes == 30:
sns.kdeplot(df['Metric'], cumulative=True, legend=False, ax=ax3)
plt.setp(ax3.get_yticklabels(), visible=False)
ax3.set_title('30 Nodes')
else:
sns.kdeplot(df['Metric'], cumulative=True, legend=False, ax=ax4)
plt.setp(ax4.get_yticklabels(), visible=False)
ax4.set_title('40 Nodes')
for i in range(4):
plot_data(df1, nodes[i], axes)
plot_data(df2, nodes[i], axes)
plot_data(df3, nodes[i], axes)
plt.show()
请注意,您可以通过使用sharey=True
infig, axes = plt.subplots(…, sharey=True)
和删除来简化上述操作plt.setp(ax.get_yticklabels(), visible=False)
推荐阅读
- plot - 你好,你能告诉我如何限制“情节”线的长度
- php - 在 PHP (PDO) 之外获取导致未定义的索引
- typescript - 有没有办法使用打字稿和续集向查询添加选项?
- html - 实时主机服务器上的 Html Css 响应问题
- coq - Coq - 你如何应用匹配子句的暗示?
- python - 减少使用 if's / elif
- mongodb - 跨文档数组元素的MongoDB唯一索引(不跨嵌套文档)
- c++ - 复制构造函数是否有助于 C++ 中的 memcpy?
- javascript - 如何用点击计数值替换图像而不是添加带有点击计数值的图像?(删除图像+添加新图像)
- arrays - 用 1 和 0 填充矩阵以使其满足给定的行和列总和的程序