Section One - Plotting with Matplotlib
学习目标:
- 解释matplotlib面向对象的绘图方法
- 使用matplotlib创建不同类型的绘图
- 使用matplotlib自定义绘图(包括标签和颜色)
- 使用matplotlib创建具有多个子图的绘图
Matplotlib是Python中最常用的绘图库,下面了解如何开始使用matplotlib创建和自定义绘图
1.1 概述
Matplotlib是一个Python绘图包,它使从存储在各种数据结构中的数据(包括列表、numpy数组和pandas数据框)创建二维图变得简单。Matplotlib使用了一种面向对象的绘图方法。这意味着可以通过向绘图中添加新的元素来逐步构建绘图
matplotlib绘图中主要会用到两个对象:
figure
对象:整体的图空间,可以包含一个或多个子图
axis
对象:在图空间中呈现的各个子图,可以把figure
对象看作是整个绘图画布,而axis
对象看作是其中的一个子图
一个图空间可以容纳一个或多个axis
对象,这种结构允许我们创建带有一个或多个子图的图形
虽然Matplotlib包含许多模块,提供不同的绘图功能,但最常用的模块是pyplot
Pyplot
提供的方法可用于向图形对象添加不同的组件,包括将各个图创建为axis
对象,也就是子图
pyplot
模块通常使用别名plt
导入,如下所示:
Id Import pyplot
import matplotlib.pyplot as plt
1.2 使用Matplotlib创建图像
要使用matplotlib的面向对象方法创建一个图,首先要使用pyplot模块中的subplots()函数创建一个图(可以称为fig
)和至少一个轴(可以称为ax
)
fig, ax = plt.subplots()
请注意,通过将fig
和ax
设置为等于pyplot.subplots()
函数的输出值,fig
和ax
被同时创建。由于没有提供其他参数,结果是一个带有一个空图的图
Id Create figure and one plot (axis object)
fig, ax = plt.subplots()
1.3 更改图片大小
使用figsize
参数设置绘图空间的宽和高
figsize = (width, height)
Id Resize figure
fig, ax = plt.subplots(figsize = (10, 6))
1.4 绘制多个子图
使用matplotlib的面向对象方法,通过创建额外的axis
对象,可以更容易地在图空间中创建多个子图
当添加多个axis
对象时,最好的做法是给它们不同的名称(如ax1
和ax2
),这样就可以很容易地单独使用每个axis
因此,需要为plt.subplots
提供新的参数,用于图的布局:(行数,列数)
plt.subplots(1, 2)
在本例中,1、2
表示布局为1行,2列
Id Figure with two plots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (10, 6))
相反地,(2,1)
表示2行,1列格局分布
fig, (ax1, ax2) = plt.subplots(2, 1, figsize = (10, 6))
由于定义了figsize=(10,6)
,figure
绘图空间会保持这个大小,无论如何设置行数或列数是多少
但是,可以调整行数、列数以及figsize
,以得到需要的大小
Id Figure with two plots
fig, (ax1, ax2) = plt.subplots(2, 1, figsize = (12, 12))
可以根据需要继续添加任意数量的axis
对象,以创建所需图形的整体布局,并根据需要继续调整图形大小
Id Figure with three plots
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize = (15, 15))
Matplotlib 面向对象方法的一个主要优点是,每个axis
都是独立的的对象,可以独立于图中的其他绘图独立地进行自定义绘制
2 使用 Matplotlib 绘制自定义图表
在本章的前面,学习了如何使用pyplot
中的subplot ()
函数创建图形和轴对象(使用别名plt
导入) :
fig,ax = plt.subplots()
现在已经知道如何使用matplotlib
创建基本的绘图,可以开始向图中的绘图添加数据了
首先导入别名plt
的matplotlib.pyplot
模块,并创建一些列表来绘制由美国国家海洋和大气管理局(NOAA)提供的*科罗拉多州博尔德市的月平均降水量(英寸)*
Id Import pyplot 导入包
import matplotlib.pyplot as plt
Id Monthly average precipitation 月平均降水量
boulder_monthly_precip = [0.70, 0.75, 1.85, 2.93, 3.05, 2.02,
1.93, 1.62, 1.84, 1.31, 1.39, 0.84]
Id Month names for plotting 月份
months = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July",
"Aug", "Sept", "Oct", "Nov", "Dec"]
2.1 使用 Matplotlib 绘制数据
可以通过调用所需的ax
对象将数据添加到绘图中,该对象是先前定义的axis
元素:
fig,ax = plt.subplots()
通过调用ax
对象的plot()
方法,并指定绘图的x
轴(水平轴)和y
轴(垂直轴)的参数如下
plot(x_axis, y_axis)
在这个例子中,你正在从之前定义的列表中添加数据,数据沿着x
轴和y
轴分布
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.plot(months,
boulder_monthly_precip)
[<matplotlib.lines.Line2D at 0x7f0b21ed3e48>]
可以注意到,输出显示了图形的对象类型以及唯一标识符(内存位置)
[<matplotlib.lines.Line2D at 0x7f81afe900b8>]
可以通过在代码末尾调用plt.show()
来隐藏该信息
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.plot(months,boulder_monthly_precip)
plt.show()
2.2 Matplotlib Plot 对象的命名约定
Python 社区中的惯例是使用ax
来命名axis
对象,但这并不是唯一的
Id Define plot space with ax named bob
fig, bob = plt.subplots(figsize=(10, 6))
Id Define x and y axes
bob.plot(months,boulder_monthly_precip)
plt.show()
2.3 创建不同类型的Matplotlib图: 散点图和条形图
默认情况下,ax.plot 将绘图创建为线图(这意味着所有的值都通过横跨绘图的连续线连接起来)
可以使用 ax 对象来创建:
- 散点图(使用
ax.scatter
) : 值显示为不连续线的单个点 - 条形图(使用
ax.bar
) : 值显示为条形,其高度指示特定点的值
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Create scatter plot
ax.scatter(months,boulder_monthly_precip)
plt.show()
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Create bar plot
ax.bar(months,boulder_monthly_precip)
plt.show()
2.4 自定义绘图标题和坐标轴标签
可以使用ax.set()
方法中的title
、xlabel
、ylabel
参数为轴添加绘图标题和标签,从而自定义和添加更多信息到绘图中
ax.set(title = "Plot title here",
xlabel = "X axis label here",
ylabel = "Y axis label here")
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.plot(months,
boulder_monthly_precip)
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation in Boulder, CO",
xlabel = "Month",
ylabel = "Precipitation (inches)")
plt.show()
2.5 自定义多行绘图标题和坐标轴标签
使用两个单词之间的新行字符**\n
**创建具有多行文本的标题和轴标签
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.plot(months,
boulder_monthly_precip)
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
2.6 标签旋转
使用plt.setp
函数设置整个绘图空间的参数,如自定义刻度标签
在下面的例子中,ax.get_xticklabels()
函数控制x轴的刻度标签,rotation
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.plot(months,
boulder_monthly_precip)
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.setp(ax.get_xticklabels(),rotation=45)
plt.show()
2.7 自定义折线、点标记形状
可以通过marker=
参数对线段、点的形状标识进行修改
Marker symbol | Marker description |
---|---|
. | point |
, | pixel |
o | circle |
v | triangle_down |
^ | triangle_up |
< | triangle_left |
> | triangle_right |
访问Matplotlib文档可以获取更多标记类型列表
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.scatter(months,
boulder_monthly_precip,
marker = ',') Id pixel
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.plot(months,
boulder_monthly_precip,
marker = 'o') Id point
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
2.8 自定义绘图颜色
可以使用color
参数自定义绘图颜色,在matplotlib
中提供的一些基本颜色选项列表如下:
b: blue
g: green
r: red
c: cyan
m: magenta
y: yellow
k: black
w: white
对于这些基本颜色,可以将color
参数设置为等于全名(例如cyan
)或者仅仅是如上表所示的键字母(例如c
)
要获得更多的颜色,请访问关于颜色的matplotlib文档
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.plot(months,
boulder_monthly_precip,
marker = 'o',
color = 'cyan') Id color=c
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.scatter(months,
boulder_monthly_precip,
marker = ',',
color = 'k') Id color=black
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.bar(months,
boulder_monthly_precip,
color = 'darkblue')
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
2.8 设置颜色透明度
使用alpha =
参数调整颜色的透明度,其值接近0.0表示更高的透明度
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.bar(months,
boulder_monthly_precip,
color = 'darkblue',
alpha = 0.3) Id 透明度设置
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
2.9 自定义条形图的颜色
通过使用参数edgeccolor=
将每个条的轮廓颜色更改为蓝色,并从前面讨论过的matplotlib
颜色选项中指定一种颜色,可以进一步自定义条形图
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.bar(months,
boulder_monthly_precip,
color = 'cyan',
edgecolor = 'darkblue') Id 轮廓颜色设置
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
2.10 自定义散点图的颜色
在使用散点图时,还可以使用c
和cmap
参数根据每个点的数据值为其分配一种颜色
c
参数允许指定将被颜色映射的值序列(例如boulder _ monthly _ precip
) ,而cmap
允许指定用于该序列的颜色映射
下面的例子使用了YlGnBu
颜色图,其中较低的值用黄色到绿色色调填充,而较高的值用越来越深的蓝色色调填充
要查看彩色地图选项列表,请访问的matplotlib cmpas文档
Id Define plot space
fig, ax = plt.subplots(figsize=(10, 6))
Id Define x and y axes
ax.scatter(months,
boulder_monthly_precip,
c = boulder_monthly_precip,
cmap = 'YlGnBu')
Id Set plot title and axes labels
ax.set(title = "Average Monthly Precipitation\nBoulder, CO",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
2.11 将数据绘制为多图
回想matplotlib
的面向对象方法,通过创建额外的axis
对象,可以很容易地在一个图形中包含多个图形:
fig, (ax1, ax2) = plt.subplots(num_rows, num_columns)
一旦定义了fig
和两个axis
对象,就可以向每个轴添加数据并定义具有独特特征的图形
在下面的示例中,ax1.bar
在第一个绘图中创建一个定制的条形图,而ax2.scatter
在第二个绘图中创建一个定制的散点图
Id Define plot space
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12)) Id 两行一列
Id Define x and y axes
ax1.bar(months,
boulder_monthly_precip,
color = 'cyan',
edgecolor = 'darkblue')
Id Define x and y axes
ax2.scatter(months,
boulder_monthly_precip,
c = boulder_monthly_precip,
cmap = 'YlGnBu')
plt.show()
2.12 为多个子图添加标题和轴标签
可以继续添加ax1
和ax2
,例如为每个单独的绘图添加标题和轴标签,就像您以前只有一个绘图时所做的那样
可以使用ax1.set()
为第一个绘图(柱状图)定义元素,使用ax2.set()
为第二个绘图(散点图)定义元素
Id Define plot space
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))
Id Define x and y axes
ax1.bar(months,
boulder_monthly_precip,
color = 'cyan',
edgecolor = 'darkblue')
Id Set plot title and axes labels
ax1.set(title = "Bar Plot of Average Monthly Precipitation",
xlabel = "Month",
ylabel = "Precipitation\n(inches)");
Id Define x and y axes
ax2.scatter(months,
boulder_monthly_precip,
c = boulder_monthly_precip,
cmap = 'YlGnBu')
Id Set plot title and axes labels
ax2.set(title = "Scatter Plot of Average Monthly Precipitation",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
现在已经有了多个图形(每个图形都有自己的标签) ,还可以为整个图形添加一个总体标题(使用指定的字体大小) ,使用:
fig.suptitle("Title text", fontsize = 16)
Id Define plot space
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))
fig.suptitle("Average Monthly Precipitation for Boulder, CO", fontsize = 16)
Id Define x and y axes
ax1.bar(months,
boulder_monthly_precip,
color = 'cyan',
edgecolor = 'darkblue')
Id Set plot title and axes labels
ax1.set(title = "Bar Plot",
xlabel = "Month",
ylabel = "Precipitation\n(inches)");
Id Define x and y axes
ax2.scatter(months,
boulder_monthly_precip,
c = boulder_monthly_precip,
cmap = 'YlGnBu')
Id Set plot title and axes labels
ax2.set(title = "Scatter Plot",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.show()
2.13 将 Matplotlib 图形保存为图像文件
可以使用以下命令轻松地将图形保存到图像文件中,例如 .png:
plt.savefig ("path/name-of-file.png")
可以保存最新的数据,如果没有为文件指定一个路径,文件将会在你当前的工作目录文件夹中创建
查看Matplotlib文档以查看用于保存图形的其他文件格式的列表
Id Define plot space
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))
fig.suptitle("Average Monthly Precipitation for Boulder, CO", fontsize = 16)
Id Define x and y axes
ax1.bar(months,
boulder_monthly_precip,
color = 'cyan',
edgecolor = 'darkblue')
Id Set plot title and axes labels
ax1.set(title = "Bar Plot",
xlabel = "Month",
ylabel = "Precipitation\n(inches)");
Id Define x and y axes
ax2.scatter(months,
boulder_monthly_precip,
c = boulder_monthly_precip,
cmap = 'YlGnBu')
Id Set plot title and axes labels
ax2.set(title = "Scatter Plot",
xlabel = "Month",
ylabel = "Precipitation\n(inches)")
plt.savefig("output/average-monthly-precip-boulder-co.png")
plt.show()
2.14 额外资源
-
关于颜色条的更多信息color bars
-
深入介绍matplotlib
3.1 自定义x轴日期刻度
Id Import required python packages
import os
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import matplotlib.dates as mdates
import seaborn as sns
import earthpy as et
Id Date time conversion registration
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
Id Get the data
Id data = et.data.get_data('colorado-flood')
Id Set working directory
os.chdir(os.path.join(et.io.HOME, 'learning','python_data_plot'))
Id Prettier plotting with seaborn
sns.set(font_scale=1.5)
sns.set_style("whitegrid")
在本节中,将学习如何在Python中使用matplotlib绘制时间序列
Id Read in the data
data_path = "data/precipitation/805325-precip-dailysum-2003-2013.csv"
boulder_daily_precip = pd.read_csv(data_path,
parse_dates=['DATE'], Id 将csv中的时间字符串转换成日期格式
na_values=['999.99'],
index_col=['DATE'])
boulder_daily_precip.head()
<div> <style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style> <table border="1" class="dataframe"> <thead> <tr style="text-align: right;"> <th></th> <th>DAILY_PRECIP</th> <th>STATION</th> <th>STATION_NAME</th> <th>ELEVATION</th> <th>LATITUDE</th> <th>LONGITUDE</th> <th>YEAR</th> <th>JULIAN</th> </tr> <tr> <th>DATE</th> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody> <tr> <th>2003-01-01</th> <td>0.0</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.03389</td> <td>-105.28111</td> <td>2003</td> <td>1</td> </tr> <tr> <th>2003-01-05</th> <td>NaN</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.03389</td> <td>-105.28111</td> <td>2003</td> <td>5</td> </tr> <tr> <th>2003-02-01</th> <td>0.0</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.03389</td> <td>-105.28111</td> <td>2003</td> <td>32</td> </tr> <tr> <th>2003-02-02</th> <td>NaN</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.03389</td> <td>-105.28111</td> <td>2003</td> <td>33</td> </tr> <tr> <th>2003-02-03</th> <td>0.4</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.03389</td> <td>-105.28111</td> <td>2003</td> <td>34</td> </tr> </tbody> </table> </div>
Id Subset the data
Id 提取8月15至10月15之间的数据
precip_boulder_AugOct = boulder_daily_precip["2013-08-15":"2013-10-15"]
Id View first few rows of data
precip_boulder_AugOct.head()
<div> <style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style> <table border="1" class="dataframe"> <thead> <tr style="text-align: right;"> <th></th> <th>DAILY_PRECIP</th> <th>STATION</th> <th>STATION_NAME</th> <th>ELEVATION</th> <th>LATITUDE</th> <th>LONGITUDE</th> <th>YEAR</th> <th>JULIAN</th> </tr> <tr> <th>DATE</th> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody> <tr> <th>2013-08-21</th> <td>0.1</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.0338</td> <td>-105.2811</td> <td>2013</td> <td>233</td> </tr> <tr> <th>2013-08-26</th> <td>0.1</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.0338</td> <td>-105.2811</td> <td>2013</td> <td>238</td> </tr> <tr> <th>2013-08-27</th> <td>0.1</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.0338</td> <td>-105.2811</td> <td>2013</td> <td>239</td> </tr> <tr> <th>2013-09-01</th> <td>0.0</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.0338</td> <td>-105.2811</td> <td>2013</td> <td>244</td> </tr> <tr> <th>2013-09-09</th> <td>0.1</td> <td>COOP:050843</td> <td>BOULDER 2 CO US</td> <td>1650.5</td> <td>40.0338</td> <td>-105.2811</td> <td>2013</td> <td>252</td> </tr> </tbody> </table> </div>
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(precip_boulder_AugOct.index.values,
precip_boulder_AugOct['DAILY_PRECIP'].values,
'-o',
color='purple')
ax.set(xlabel="Date", ylabel="Precipitation (Inches)",
title="Daily Precipitation \nBoulder, Colorado 2013")
Id Format the x axis
Id 对x轴进行日期格式化
ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=2))
ax.xaxis.set_major_formatter(DateFormatter("%m-%d"))
plt.show()
3.2 对Matplotlib进行日期格式化
在 matplotlib 中,也可以使用 DateFormatter 模块更改绘图轴上的日期格式
需要从 matplotlib 导入 DateFormatter,然后使用以下语法指定日期 DateFormatter 要使用的格式:
%Y-4位数年份 %y-2位数年份 %m-月份 %d-天
实现自定义日期的步骤:
-
定义日期格式:
myFmt = DateFormatter("%m/%d")
,这个日期格式是月/日,所以它看起来像这样: 10/05,代表10月5日 -
调用
set_major_formatter()
方法:
ax.xaxis.set_major_formatter(myFmt)
将上面定义的日期格式应用于绘图空间中
Id Plot the data
fig, ax = plt.subplots(figsize=(10,6))
ax.scatter(precip_boulder_AugOct.index.values,
precip_boulder_AugOct['DAILY_PRECIP'].values,
color='purple')
ax.set(xlabel="Date", ylabel="Precipitation (Inches)",
title="Daily Precipitation (inches)\nBoulder, Colorado 2013")
Id Define the date format
date_form = DateFormatter("%m/%d")
ax.xaxis.set_major_formatter(date_form)
3.3 X轴的日期刻度
特定的时间刻度可以沿着x轴添加,例如:大的刻度可以表示每个新的工作周的开始,小的刻度可以表示每个工作日
函数xaxis.set_major_locator()
控制大刻度的位置,函数xaxis.set_minor_locator
控制小刻度
Id Plot the data
fig, ax = plt.subplots(figsize=(10,6))
ax.scatter(precip_boulder_AugOct.index.values,
precip_boulder_AugOct['DAILY_PRECIP'].values,
color='purple')
ax.set(xlabel="Date", ylabel="Precipitation (Inches)",
title="Daily Precipitation (inches)\nBoulder, Colorado 2013")
Id 定义日期格式
date_form = DateFormatter("%m/%d")
ax.xaxis.set_major_formatter(date_form)
Id 确保每隔一周刻度减小一次
ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=1))
Id ax.xaxis.set_minor_locator(mdates.DayLocator(1))
参考资料:
https://www.earthdatascience.org/courses/scientists-guide-to-plotting-data-in-python-textbook/