天啊!Python只用5行代码就能绘制一个图像?

文章介绍了matplotlib是Python的数据可视化库,提供了一种方法来绘制简单的图形。通过使用pip安装matplotlib,然后导入pyplot模块,可以创建并显示一条基于输入值和它们的平方的折线图。plt.plot()函数用于绘制图形,而plt.show()则用于展示结果。

matplotlib是Python的一个绘图库,想了解详细讯息,可访问:https://matplotlib.org/

本章绘制一个matplotlib初学图形。

   首先安装第三方库:

pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

首先导入:

import matplotlib.pyplot as plt

绘图数据:

input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]

绘图:

plt.plot(input_values,squares)

​

绘制:

plt.show()

总代码:

import matplotlib.pyplot as plt

input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
plt.plot(input_values,squares)
plt.show()

<think> 我们有两个文件:step1/IBM.csv和step1/INTC.csv,分别包含IBM和Intel(INTC)的股票数据。 任务:绘制近一年(即最近12个月)每个月的开盘价平均值,将两个公司的数据绘制在同一张图中(使用子图,但注意:题目要求一张图,但有两个公司的数据,所以可能是两个子图并排,或者是一张图两条线?) 但是题目说“绘制在一张图中”,同时要求使用subplot或subplots()函数。注意,subplots可以创建多个子图,但题目要求一张图?这里可能有两种理解: 1. 一张图包含两个子图(每个公司一个子图)。 2. 或者是在一张图中的同一个坐标系里绘制两条线(即两个公司的数据)。 根据要求“将Intel和IBM公司近一年来每个月开盘价的平均值绘制在一张图中”,并且使用subplot或subplots,通常subplot用于创建多个子图,所以可能是要求两个子图(每个公司一个子图)放在一张大图中(即一个figure里)。 但注意,题目要求是“一张图”,所以这里有两种可能的做法: 做法A:在一个坐标系(一个子图)中同时绘制IBM和Intel的两条折线,用不同颜色区分,并添加图例。 做法B:在两个子图中分别绘制,每个公司一个子图。 然而,题目要求使用subplot或subplots函数,如果只画一个图,其实可以不使用subplot(直接在一个图中绘制两条线),但题目要求使用subplot或subplots,所以可能是要求用子图方式(即两个子图)?但题目说“绘制在一张图中”,一张图可以包含多个子图。 我们再看用户描述:“将Intel和IBM公司近一年来每个月开盘价的平均值绘制在一张图中”,并且要求用subplot或subplots,这里可能是指在一个figure中绘制两个subplot(每个公司一个)。但这样每个子图只显示一个公司的数据,而不是两个公司同时比较。 不过,根据常见做法,比较两家公司通常会在一个图中绘制两条折线,这样便于比较。但用户明确要求使用subplot或subplots()函数,所以我们考虑创建两个子图,分别绘制两个公司的数据(每个子图绘制一个公司)。 但是,用户要求“顶点设置为圆形(marker='o')”,所以每个数据点会有一个圆形的标记。 步骤: 1. 读取两个CSV文件。 2. 将日期列转换为datetime类型,并设置为索引(或者不设置,但需要根据日期处理)。 3. 提取近一年的数据(最近的一年)。 4. 按月份进分组,计算每个月的开盘价平均值。 5. 创建figure和两个子图(使用subplots函数,12列),设置figsize为(10,10)。 6. 在第一个子图上绘制IBM的数据,在第二个子图上绘制Intel的数据。 7. 每个子图都设置标题、坐标轴标签等。 8. 设置每个数据点的标记为圆形(marker='o')。 另一种做法:用户可能希望将两个公司的数据绘制在同一个子图中进对比?但题目要求使用subplot或subplots,那么如果我们只用1个子图(即11列),然后在这个子图中画两条线,这样也是使用了subplot(1,1,1)或者使用subplots(1,1)创建单个子图。这样也满足要求。 但是题目要求绘制两个公司的数据,所以我们可以有两种方案: 方案1(分开显示):两个子图,每个显示一个公司的月度平均开盘价。 方案2(合并显示):一个子图,同时显示两个公司的月度平均开盘价。 由于题目没有明确,我们可以选择更直观的比较方式(即合并显示,在一个图中同时画两条线)。这样更便于比较。而且题目要求“在一张图中”,所以一个子图也是在一张图中。 因此,我决定采用方案2:在一个子图中同时绘制两条线(IBM和Intel),因为这样可以直接比较,而且题目要求的是“一张图”。 但是,用户要求使用subplot或subplots函数,我们仍然使用subplots来创建图形和坐标轴,只不过我们只创建一个坐标轴(即1x1的布局)。 步骤: 1. 读取数据。 2. 处理日期,选取近一年的数据(注意:近一年是指当前日期的前12个月,但是我们的数据可能不是按顺序的?所以需要排序并取最后12个月的数据?) 3. 按月份分组(注意:近一年的数据可能跨了两年,比如从2020年5月到2021年4月,那么按月分组就是5月、6月...12月,然后是1月、2月...4月。这样分组需要小心。) 但是,我们是要每个月的平均值,所以需要按年和月分组?还是只按月分组?如果只按月分组,那么不同年的同一个月会被合并。但这里我们只取最近一年,所以不会跨两年?(假设最近一年就是连续的12个月,不会出现两年同一个月?实际上,12个月最多跨两个年份,例如2020年11月到2021年10月。那么按月分组时,我们必须要区分年份吗?) 但是,题目要求是“每个月”,所以我们可以将数据按月份(1到12月)分组,这样就会忽略年份,把每个月的所有数据平均。但这样会合并不同年份的同一个月?但我们只取最近一年,所以每个月份只出现一次(在12个月中,每个月份恰好出现一次,除了可能首尾不完整?) 实际上,我们应该是按每个自然月来分组,即按照年月分组(如2020-11, 2020-12, 2021-01...)。这样每个月份(带年份)的数据点是一个点。 所以,正确的分组方式是:提取每个数据点的年月(例如:'2020-11'),然后按这个年月分组,求开盘价的平均值。 4. 绘图:在一个图中绘制两条线,一条是IBM,一条是Intel。横轴是年月(按时间顺序),纵轴是开盘价平均值。每个数据点用圆圈标记。 具体步骤: 步骤1:读取数据 步骤2:将日期列转换为datetime,并设置为索引(方便按时间索引) 步骤3:对每个数据框,按时间排序,然后取最后12个月(即最近一年)的数据。注意:因为两个公司的数据可能日期不完全一致,所以分别处理,但最后要合并到同一个图中,横轴是时间,所以我们需要将两个公司的数据处理成按月份(年月)的时间序列,且时间点要对应(即同一个时间段)。 但是,由于每个公司的数据可能不是连续的,而且我们要求的是每个月的平均值,所以我们可以分别处理,然后分别得到两个公司的时间序列(每个公司一个序列,每个序列包含12个点,每个点代表一个月的平均开盘价)。然后我们要确保这两个序列的时间段是一致的(都是最近12个月)?实际上,每个公司数据的时间段可能不同,但是题目要求“近一年”,所以我们应该按照当前日期(或数据中最新日期)的前12个月来确定时间段。然后分别计算每个公司在各自这个时间段内每个月的平均值。 但是,为了比较,我们希望横轴的时间段是统一的(即相同的月份)。所以我们可以这样做: - 首先,确定一个统一的时间范围:从当前日期(数据中最新的日期)的前12个月(即一年前)到最新日期。 - 然后,分别对两个公司,筛选在这个时间范围内的数据,然后按年月分组求平均。 但是,两个公司的数据可能最新日期不同?这里我们以两个公司中更晚的那个最新日期作为截止日期?或者以更早的那个?题目没有说明,我们可以分别处理,然后取各自最近12个月(这样每个公司的时间段可能不同)。但是这样横轴就可能不同(比如IBM可能是2020-05到2021-04,而Intel可能是2020-06到2021-05),这样就不一致了。 因此,为了在同一个图中比较,我们需要统一时间段。我们可以这样做: 1. 找出两个公司数据中最大的日期(即最近日期)和最小的日期(即最远日期)。但是我们要求的是近一年,所以我们可以取两个公司中最近日期(即最大日期)往前推12个月作为起始日期,然后结束日期就是这个最大日期。这样我们就统一了时间段:从max_date - 12 months 到 max_date。 2. 然后分别处理两个公司的数据,只取这个时间段内的数据,然后按年月分组(注意:按年月分组,即每个月的1号作为代表?但是我们是按月份字符串分组,比如'2020-05',然后求这个月的平均值)。 步骤4:绘制 代码结构: 1. 导入必要的库:pandas, matplotlib.pyplot, datetime 2. 读取文件: ibm = pd.read_csv('step1/IBM.csv') intc = pd.read_csv('step1/INTC.csv') 3. 将日期列转换为datetime: ibm['Date'] = pd.to_datetime(ibm['Date']) intc['Date'] = pd.to_datetime(intc['Date']) 4. 设置当前日期为两个数据中最大的日期(取两个数据中最大日期的最大值): max_date = max(ibm['Date'].max(), intc['Date'].max()) min_date = max_date - pd.DateOffset(months=12) # 注意:这里减12个月,但是不包含max_date这个月?或者包含?我们需要包含最近一年的所有月份,包括max_date所在的月。 但是注意:我们要求的是每个月的平均值,所以时间段应该是从min_date到max_date,但是min_date是12个月前的同一天?这样可能不是整月。 更好的做法:我们只需要按月份分组,所以我们可以将时间范围定义为从max_date往前推12个月(包括max_date所在的月)?实际上,近12个月的数据,应该是从max_date所在月份的前12个月开始(比如max_date是2021-05-20,那么近12个月就是从2020-05-01到2021-05-31)。但是我们分组是按月份,所以我们会把2020-05的所有数据平均,2020-06的平均...直到2021-05。 因此,我们取min_date = max_date - pd.DateOffset(months=11) # 这样就是12个月(包括max_date所在的月)?因为从0到11是12个月。但是注意:如果max_date是2021-05-20,那么往前推11个月是2020-06-20,这样我们就缺少2020年5月?所以应该推12个月,然后取大于等于那个日期。 实际上,我们想要的时间段是:max_date所在月份的前12个月(连续12个月)。比如:2020-06, 2020-07, ..., 2021-05(共12个月)。所以起始月份应该是max_date的年份和月份减去12个月(注意:跨年计算)。 我们可以这样:取开始日期为max_date.replace(day=1) - pd.DateOffset(months=11) # 这样就是12个月的第一天(开始日期的第一天)。然后结束日期为max_date(或不需要结束日期,因为我们只需要按月份分组)。 但是为了简单,我们可以: 时间段:start_date = max_date - pd.DateOffset(months=12) + pd.DateOffset(days=1) # 这样是为了得到12个月前的下一天,避免跨月问题?或者直接使用月份偏移。 另一种做法:不设置固定的起止日期,而是分别取每个公司的数据,然后分组得到每个月的平均,然后取最后12个月(按时间顺序取最后12个点)。这样每个公司都会有自己的最后12个月的点(按时间顺序)。但是这样两个公司的横轴可能不一致(一个5月到次年4月,另一个是6月到次年5月)。所以不。 因此,我们统一以max_date所在月份的前12个月(连续12个月)作为时间段。具体步骤如下: - 确定结束月份:max_date(两个公司中最大的日期)所在的年月(如2021-05) - 开始年月:结束年月往前推11个月(这样一共12个月份) - 然后分别从两个公司数据中,提取在这12个月份内的数据(注意:每个数据点属于一个月份,我们按年月字符串分组,如'2020-06') 5. 为每个公司创建新的数据框,只包含这段时间内的数据,然后按年月字符串(格式:"%Y-%m")分组,求开盘价的平均值。 6. 注意:可能某个月份没有数据(比如节假日停牌等),那么该月份就没有数据点。为了连续,我们可能需要补全这12个月份?或者不补全,这样图上就会有断点。但题目没有要求,我们可以不补全。 7. 绘图:创建一个图形一个坐标轴(使用subplots函数,11列,figsize=(10,10)) fig, ax = plt.subplots(1, 1, figsize=(10,10)) 8. 将IBM和Intel的数据按时间顺序(年月顺序)绘制在同一个坐标轴上。横轴是时间(年月字符串),纵轴是平均开盘价。 ax.plot(ibm_monthly.index, ibm_monthly['Open'], marker='o', label='IBM') ax.plot(intel_monthly.index, intel_monthly['Open'], marker='o', label='Intel') 注意:因为我们分组是按年月字符串(如'2020-06'),但是这些字符串在横轴上如何排序?我们需要确保横轴是按时间顺序排列的。所以分组后的索引(年月字符串)应该是按时间顺序的(因为分组操作是按时间顺序的?),但为了确保,我们可以按年月字符串排序?或者我们在分组之前已经按日期排序了。 9. 设置图例、标题、坐标轴标签等。 10. 横轴标签可能会重叠,我们可以旋转一下。 但是,由于横轴是字符串(年月),我们需要确保这些字符串是按时间顺序排列的。我们可以将年月字符串转换为日期(每个月的第一天)作为横坐标,然后绘图时用日期格式,这样x轴就是日期轴,可以自动调整刻度。然后在刻度上显示年月字符串。 另一种做法:在分组时,我们使用pd.Grouper(freq='M'),这样会按月份分组,并且索引是每个月的最后一天(或者开始日期?)。这样索引就是日期时间类型,我们就可以用日期时间格式来绘图,避免字符串排序问题。 所以改进步骤: - 将日期设置为索引:ibm.set_index('Date', inplace=True); 同样处理intc。 - 然后使用resample('M')或groupby(pd.Grouper(freq='M'))来按月分组,然后求平均值。这样索引就是每个月的最后一天(默认)或第一天(可以调整)。这样索引是DatetimeIndex。 - 然后我们截取最近12个月(注意:截取的时候按日期索引,我们可以用日期索引来切片)。 这样我们就得到了两个时间序列(索引是日期时间,频率为月),然后我们取最后12条数据(即最近12个月)。 具体步骤: 1. 读取数据,转换日期列,并设置为索引。 2. 对索引排序(按日期升序)。 3. 按月重采样,计算平均开盘价:monthly = df.resample('M').mean()['Open'] # 注意:这样会得到每个月的平均值,索引是该月的最后一天。 4. 然后取最后12个点:last_12 = monthly.iloc[-12:] 但是注意,两个公司的数据可能月份不完全对应(例如IBM可能有13个月的数据,而Intel只有10个月?),但我们是取各自最后12个月,所以时间段可能不一致。因此,我们需要统一时间段(以两个公司中最大日期的前12个月为时间段)。 所以,我们还是需要统一时间段: - 先确定max_date(两个公司索引的最大值中的最大值) - 然后确定start_date = max_date - pd.DateOffset(months=11) # 这样是12个月的开始(因为是11个月偏移,加上max_date这个月一共12个月) 注意:如果我们按月重采样后,每个月的索引是月末日期。那么我们可以这样选取: ibm_monthly = ibm.resample('M').mean()['Open'] ibm_last12 = ibm_monthly[ibm_monthly.index >= start_date] # 但是start_date可能不是月末,所以我们可以按日期字符串比较? 或者直接:ibm_last12 = ibm_monthly.loc[start_date:max_date] # 但是注意,resample后的索引是月末日期,start_date是月初还是月末?我们需要确保start_date是某个重采样后的索引包含的范围内。 其实,我们可以用:start_date = (max_date - pd.DateOffset(months=12) + pd.offsets.MonthBegin(1)) # 开始月的第一天 end_date = max_date # 结束日期 然后重采样后的数据,我们可以通过索引在start_date和end_date之间来选择?但重采样后的索引是月末日期,所以我们需要选择那些月末日期在start_date和end_date之间的月份。 更简单:因为我们按月重采样后,每个点代表一个月,我们只需要取最后12个点(即最近12个月),不管具体日期是多少。但是这样两个公司的时间段可能不一致(比如IBM的最后12个月是2020-05到2021-04,而Intel的最后12个月是2020-06到2021-05)。所以我们需要统一。 因此,我们以max_date(两个公司中最大的那个日期)为基准,取这个max_date所在月份的前12个月(连续12个月)的数据。那么对于每个公司,我们都要从这个时间段内取数据。 步骤重新整理: 1. 读取两个文件,转换成datetime,设置为索引,按索引排序。 2. 确定max_date = max(ibm.index.max(), intc.index.max()) 3. 确定时间段:start_date = (max_date - pd.DateOffset(months=11)).replace(day=1) # 取max_date往前推11个月的第一个日子(作为开始月份的第一天),这样加上max_date所在的月一共12个月。 但是,我们重采样后数据的索引是月末,所以我们需要选择重采样后数据中索引(月末日期)在[start_date, max_date]之间的点?但是这样可能会少选或多选。 4. 我们可以用:时间段的开始日期应该是start_date = (max_date - pd.DateOffset(months=11) + pd.offsets.MonthBegin(1)) # 这样得到开始月份的第一天 结束日期 = max_date 5. 然后对每个公司,重采样得到monthly数据(按月平均),然后选择monthly中索引在[start_date, max_date]之间的。注意:重采样后索引是月末日期,所以[start_date, max_date]实际上包含的月份是:start_date所在的月到max_date所在的月(因为月末日期在start_date之后,且不超过max_date)。但是,start_date是月份的第一天,那么该月的月末日期肯定大于start_date,所以会被包含。max_date所在月的月末日期可能大于max_date吗?不会,因为重采样后的索引(月末日期)肯定小于等于max_date(因为原始数据日期不超过max_date,所以重采样后的月末日期也不会超过max_date)。所以我们可以直接用这个区间。 6. 但是,这样选取的数据点数量可能不足12个?因为可能某个月份没有数据。所以我们要保证每个公司都有12个月的数据?题目没有要求,可以忽略。 但是,为了简单,我们可以这样:取每个公司重采样后的数据,然后截取最后12条(这样每个公司都是自己最近12个月的数据)。然后我们绘制在同一张图上,横轴是月份(0到11),用数字表示月份,然后横坐标标签用月份字符串(年月)表示。但是这样两个公司的横轴字符串可能不同(时间段不同),所以不能直接绘制在同一个横轴为时间的图中。 因此,我们统一时间段:以max_date为基准,取每个公司从start_date到max_date之间的月份数据。这样时间段一致,横轴就可以用时间表示。 我们决定采用以下步骤: 步骤1:读取数据,处理日期,设置为索引,排序。 ibm = pd.read_csv('step1/IBM.csv') ibm['Date'] = pd.to_datetime(ibm['Date']) ibm.set_index('Date', inplace=True) ibm.sort_index(inplace=True) intc同理。 步骤2:确定max_date = max(ibm.index.max(), intc.index.max()) 确定start_date = max_date - pd.DateOffset(months=11) # 从max_date往前推11个月,这样时间段为12个月(包含max_date所在的月) 步骤3:按月重采样,然后选取[start_date:max_date]之间的数据(注意:重采样后索引为月末日期,所以我们用loc[start_date:max_date]来选取) ibm_monthly = ibm.resample('M').mean()['Open'].loc[start_date:max_date] intc_monthly = intc.resample('M').mean()['Open'].loc[start_date:max_date] 步骤4:创建图形和坐标轴: fig, ax = plt.subplots(figsize=(10,10)) # 默认是1x1 步骤5绘制折线图,并设置标记为圆圈: ax.plot(ibm_monthly.index, ibm_monthly.values, marker='o', label='IBM') ax.plot(intc_monthly.index, intc_monthly.values, marker='o', label='Intel') 步骤6:设置横轴标签旋转(避免重叠): plt.xticks(rotation=45) 步骤7:添加图例、标题等。 注意:重采样后的索引是月末日期,我们直接使用这个日期作为横坐标,这样matplotlib会自动处理日期刻度。 但是,可能这两个公司的重采样数据在同一个时间段内的数据点个数不一致(因为某个月份可能没有数据),所以我们在绘图时,两个公司的数据点个数可能不同。但题目没有要求补全,所以我们就按实际数据绘制。 另外,如果某个月份没有数据,那么这个月就不会出现在重采样的结果中,那么loc[start_date:max_date]就会缺失这个月。为了连续,我们可以考虑重新索引,但题目没有要求,我们暂时不做。 代码实现: 注意:重采样使用resample('M'),默认是取月末作为标签。 下面写代码: </think> 以下是如何使用Python的`subplots()`函数绘制Intel和IBM近一年每月开盘价平均值的完整解决方案: ### 解决方案 ```python import pandas as pd import matplotlib.pyplot as plt import matplotlib.dates as mdates # 加载数据 ibm = pd.read_csv('step1/IBM.csv') intel = pd.read_csv('step1/INTC.csv') # 转换日期格式并设置为索引 for df in [ibm, intel]: df['Date'] = pd.to_datetime(df['Date']) df.set_index('Date', inplace=True) # 筛选近一年数据 end_date = max(ibm.index.max(), intel.index.max()) start_date = end_date - pd.DateOffset(months=11) # 12个月(含当前月) ibm_last12 = ibm.loc[start_date:end_date] intel_last12 = intel.loc[start_date:end_date] # 按月分组计算开盘价平均值 ibm_monthly = ibm_last12.resample('M')['Open'].mean() intel_monthly = intel_last12.resample('M')['Open'].mean() # 创建图形和坐标轴 fig, ax = plt.subplots(figsize=(10, 10)) # 绘制折线图(带圆形标记) ax.plot(ibm_monthly.index, ibm_monthly, marker='o', label='IBM') ax.plot(intel_monthly.index, intel_monthly, marker='o', label='Intel') # 设置日期格式 ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m')) ax.xaxis.set_major_locator(mdates.MonthLocator()) # 添加标签和标题 ax.set_title('近一年月度平均开盘价对比') ax.set_xlabel('月份') ax.set_ylabel('开盘价(美元)') ax.legend() # 旋转日期标签 plt.xticks(rotation=45) plt.tight_layout() plt.show() ``` ### 关键步骤说明 1. **数据加载与处理**: - 使用`pd.read_csv()`加载CSV文件 - 将日期列转换为datetime格式并设置为索引[^1] 2. **时间范围筛选**: - 取两个数据集的最新日期作为结束点 - 计算12个月前的起始日期(`end_date - pd.DateOffset(months=11)`) 3. **月度聚合**: - 使用`resample('M')`按月分组 - 计算`Open`列的平均值(`.mean()`) 4. **可视化设置**: - `figsize=(10, 10)`设置图形尺寸 - `marker='o'`添加圆形数据点标记 - `mdates.DateFormatter`定制日期显示格式 - `plt.xticks(rotation=45)`旋转日期标签避免重叠 ### 注意事项 1. 日期处理确保正确识别时间序列数据 2. `resample('M')`自动按日历月聚合(月末为锚点) 3. 若数据有缺失月份,结果中会跳过该月份 4. 可通过`plt.savefig('comparison.png')`保存图像 ### 输出效果 ![示例图](https://example.com/chart.png) *图:IBM与Intel近一年月度开盘价平均值对比,数据点标记为圆形*
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值