Matplotlib 显示额外的 x 标签集与常规 x 标签重叠
Matplotlib shows extra set of x labels overlapping regular x labels
我在使用 matplotlib 时遇到了这个问题,我无法隐藏自动生成的、不需要的 xlabels,这些 xlabels 似乎是凭空冒出来的。
这是我的代码(在这个重现问题的最小示例中减少了实际代码):
import datetime as dt
import matplotlib.pyplot as plt
import pandas as pd
data = pd.read_csv("TestData.csv")
# Convert string to pd.Timestamp
data["datetime"] = data["datetime"].transform(lambda d:
dt.datetime.strptime(d, '%Y-%m-%d %H:%M:%S'))
data.set_index("datetime")
# start and end dates of data in CSV
max_date = data["datetime"].max()
min_date = data["datetime"].min()
# make figure
fig = plt.figure(figsize=[24, 12], dpi=300)
ax = data.plot.line(x="datetime",
y="totalAIAD",
color="xkcd:aquamarine")
delta = max_date - min_date # total span of time for the report
time_unit = pd.to_timedelta(5, unit='m') # 5 minute ticks
floor_unit = 'T'
# floor for cleaner ticks
date = min_date.floor(floor_unit)
xticks = []
while date + time_unit <= max_date:
date = date + time_unit # create date ticks for x axis
xticks.append(date)
ax.axes.set_xticks(xticks)
str_xticks = []
for xtick in xticks:
str_xticks.append(xtick.strftime('%H:%M:%S'))
ax.axes.set_xticklabels(str_xticks, rotation=45, ha='right')
#plt.suptitle("Stream Processor and Anomaly Detector Execution times")
#plt.title("From " + min_date.strftime('%Y-%m-%d %H:%M:%S') + " to "
# + max_date.strftime('%Y-%m-%d %H:%M:%S'))
plt.xlabel(
"Time",
fontdict={
'family': 'monospace',
'color': 'xkcd:black',
'weight': 'normal',
'size': 14,
},
labelpad=6
)
plt.ylabel(
"Delays (ms)",
fontdict={
'family': 'monospace',
'color': 'xkcd:black',
'weight': 'normal',
'size': 14,
},
labelpad=6
)
[t.set_color('red') for t in ax.xaxis.get_ticklines()]
[t.set_color('red') for t in ax.xaxis.get_ticklabels()]
# vertical range for values (0 to configured MAX_Y)
plt.ylim((0, 50))
plt.grid(True, axis='y', alpha=0.5)
plt.axhline(y=10, color='r', linestyle='-')
plt.show()
plt.close(fig)
这需要 TestData.csv: https://www.toptal.com/developers/hastebin/uqepujujav.apache
它产生以下输出:
如您所见,只有我在代码中设置的 xtick 标签是红色的。不需要的(11:30、11:45 和 12:15)不受颜色影响。它们也不受我移除它们的所有尝试的影响。 (我尝试了 ax.set_xticks([])
、ax.set_xticklabels([])
、plt.xticks([])
、ax.xaxis.set_major_locator(ticker.NullLocator())
)。
有什么想法吗?我失去了摆脱这些标签的希望。
通过使用 pandas 绘制日期作为 x-axis,自动设置 AutoDateLocator
和 AutoDateFormatter
。这些设置自己的刻度,独立于 set_xticks
(并且在缩放时也会计算新的刻度)。另见 matplotlib's date tick tutorial。
如示例中所示, pandas plotting doesn't work easy with customized date formatting。您可以直接通过 matplotlib 绘图。这是代码的可能改编:
import matplotlib.pyplot as plt
from matplotlib.dates import MinuteLocator, ConciseDateFormatter
import pandas as pd
import datetime as dt
data = pd.read_csv('TestData.csv', parse_dates=True)
data["datetime"] = data["datetime"].transform(lambda d: dt.datetime.strptime(d, '%Y-%m-%d %H:%M:%S'))
data.set_index("datetime")
fig, ax = plt.subplots(figsize=[24, 12], dpi=300)
ax.plot("datetime", "totalAIAD", data=data, color="xkcd:aquamarine")
locator = MinuteLocator(interval=5)
formatter = ConciseDateFormatter(locator)
formatter.formats = ['%y', # ticks are mostly years
'%b', # ticks are mostly months
'%d', # ticks are mostly days
'%H:%M', # hrs
'%H:%M:%S', # min
'%S.%f', ] # secs
formatter.zero_formats = [''] * len(formatter.formats)
formatter.offset_formats = [''] * len(formatter.formats) # this would write out the current date at the lower right
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.set_xlabel("Time", fontdict={'family': 'monospace', 'color': 'xkcd:black', 'weight': 'normal', 'size': 14},
labelpad=6)
ax.set_ylabel("Delays (ms)", fontdict={'family': 'monospace', 'color': 'xkcd:black', 'weight': 'normal', 'size': 14},
labelpad=6)
[t.set_color('red') for t in ax.xaxis.get_ticklines()]
[t.set_color('red') for t in ax.xaxis.get_ticklabels()]
ax.set_ylim((0, 50))
ax.margins(x=0)
ax.grid(True, axis='y', alpha=0.5)
ax.axhline(y=10, color='r', linestyle='-')
fig.autofmt_xdate() # automatically makes the x-labels rotate
plt.tight_layout()
plt.show()
我在使用 matplotlib 时遇到了这个问题,我无法隐藏自动生成的、不需要的 xlabels,这些 xlabels 似乎是凭空冒出来的。
这是我的代码(在这个重现问题的最小示例中减少了实际代码):
import datetime as dt
import matplotlib.pyplot as plt
import pandas as pd
data = pd.read_csv("TestData.csv")
# Convert string to pd.Timestamp
data["datetime"] = data["datetime"].transform(lambda d:
dt.datetime.strptime(d, '%Y-%m-%d %H:%M:%S'))
data.set_index("datetime")
# start and end dates of data in CSV
max_date = data["datetime"].max()
min_date = data["datetime"].min()
# make figure
fig = plt.figure(figsize=[24, 12], dpi=300)
ax = data.plot.line(x="datetime",
y="totalAIAD",
color="xkcd:aquamarine")
delta = max_date - min_date # total span of time for the report
time_unit = pd.to_timedelta(5, unit='m') # 5 minute ticks
floor_unit = 'T'
# floor for cleaner ticks
date = min_date.floor(floor_unit)
xticks = []
while date + time_unit <= max_date:
date = date + time_unit # create date ticks for x axis
xticks.append(date)
ax.axes.set_xticks(xticks)
str_xticks = []
for xtick in xticks:
str_xticks.append(xtick.strftime('%H:%M:%S'))
ax.axes.set_xticklabels(str_xticks, rotation=45, ha='right')
#plt.suptitle("Stream Processor and Anomaly Detector Execution times")
#plt.title("From " + min_date.strftime('%Y-%m-%d %H:%M:%S') + " to "
# + max_date.strftime('%Y-%m-%d %H:%M:%S'))
plt.xlabel(
"Time",
fontdict={
'family': 'monospace',
'color': 'xkcd:black',
'weight': 'normal',
'size': 14,
},
labelpad=6
)
plt.ylabel(
"Delays (ms)",
fontdict={
'family': 'monospace',
'color': 'xkcd:black',
'weight': 'normal',
'size': 14,
},
labelpad=6
)
[t.set_color('red') for t in ax.xaxis.get_ticklines()]
[t.set_color('red') for t in ax.xaxis.get_ticklabels()]
# vertical range for values (0 to configured MAX_Y)
plt.ylim((0, 50))
plt.grid(True, axis='y', alpha=0.5)
plt.axhline(y=10, color='r', linestyle='-')
plt.show()
plt.close(fig)
这需要 TestData.csv: https://www.toptal.com/developers/hastebin/uqepujujav.apache
它产生以下输出:
如您所见,只有我在代码中设置的 xtick 标签是红色的。不需要的(11:30、11:45 和 12:15)不受颜色影响。它们也不受我移除它们的所有尝试的影响。 (我尝试了 ax.set_xticks([])
、ax.set_xticklabels([])
、plt.xticks([])
、ax.xaxis.set_major_locator(ticker.NullLocator())
)。
有什么想法吗?我失去了摆脱这些标签的希望。
通过使用 pandas 绘制日期作为 x-axis,自动设置 AutoDateLocator
和 AutoDateFormatter
。这些设置自己的刻度,独立于 set_xticks
(并且在缩放时也会计算新的刻度)。另见 matplotlib's date tick tutorial。
如示例中所示
import matplotlib.pyplot as plt
from matplotlib.dates import MinuteLocator, ConciseDateFormatter
import pandas as pd
import datetime as dt
data = pd.read_csv('TestData.csv', parse_dates=True)
data["datetime"] = data["datetime"].transform(lambda d: dt.datetime.strptime(d, '%Y-%m-%d %H:%M:%S'))
data.set_index("datetime")
fig, ax = plt.subplots(figsize=[24, 12], dpi=300)
ax.plot("datetime", "totalAIAD", data=data, color="xkcd:aquamarine")
locator = MinuteLocator(interval=5)
formatter = ConciseDateFormatter(locator)
formatter.formats = ['%y', # ticks are mostly years
'%b', # ticks are mostly months
'%d', # ticks are mostly days
'%H:%M', # hrs
'%H:%M:%S', # min
'%S.%f', ] # secs
formatter.zero_formats = [''] * len(formatter.formats)
formatter.offset_formats = [''] * len(formatter.formats) # this would write out the current date at the lower right
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.set_xlabel("Time", fontdict={'family': 'monospace', 'color': 'xkcd:black', 'weight': 'normal', 'size': 14},
labelpad=6)
ax.set_ylabel("Delays (ms)", fontdict={'family': 'monospace', 'color': 'xkcd:black', 'weight': 'normal', 'size': 14},
labelpad=6)
[t.set_color('red') for t in ax.xaxis.get_ticklines()]
[t.set_color('red') for t in ax.xaxis.get_ticklabels()]
ax.set_ylim((0, 50))
ax.margins(x=0)
ax.grid(True, axis='y', alpha=0.5)
ax.axhline(y=10, color='r', linestyle='-')
fig.autofmt_xdate() # automatically makes the x-labels rotate
plt.tight_layout()
plt.show()