程序員用來做筆記的網(wǎng)站搜索引擎是指什么
趨勢(一)利用python繪制折線圖
折線圖( Line Chart)簡介
折線圖用于在連續(xù)間隔或時間跨度上顯示定量數(shù)值,最常用來顯示趨勢和關系(與其他折線組合起來)。折線圖既能直觀地顯示數(shù)量隨時間的變化趨勢,也能展示兩個變量的關系。
快速繪制
-
基于matplotlib
import matplotlib.pyplot as plt import numpy as np# 自定義數(shù)據(jù) values = np.cumsum(np.random.randn(1000,1))# 繪制折線圖 plt.plot(values) plt.show()
-
基于seaborn
import seaborn as sns import matplotlib.pyplot as plt import numpy as np# 自定義數(shù)據(jù) values = np.cumsum(np.random.randn(1000,1))# 繪制折線圖 sns.lineplot(x=np.array(range(1, 1001)), y=values.ravel()) # 使用 ravel() 將 values 轉化為一維 plt.show()
-
基于plotly
import plotly.graph_objects as go import numpy as np# 自定義數(shù)據(jù) values = np.cumsum(np.random.randn(1000,1))# 繪制折線圖 fig = go.Figure(data=go.Scatter(x=list(range(1, 1001)), y=values.ravel(), mode='lines')) fig.show()
-
基于pandas
import numpy as np import matplotlib.pyplot as plt import pandas as pd# 自定義數(shù)據(jù) values = np.cumsum(np.random.randn(1000,1)) df = pd.DataFrame(values, columns=['Values'])# 繪制折線圖 df.plot() plt.show()
定制多樣化的折線圖
自定義折線圖一般是結合使用場景對相關參數(shù)進行修改,并輔以其他的繪圖知識。參數(shù)信息可以通過官網(wǎng)進行查看,其他的繪圖知識則更多來源于實戰(zhàn)經(jīng)驗,大家不妨將接下來的繪圖作為一種學習經(jīng)驗,以便于日后總結。
通過matplotlib繪制多樣化的折線圖
matplotlib主要利用plot
繪制折線圖,可以通過matplotlib.pyplot.plot了解更多用法
-
修改參數(shù)
import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pdplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽# 自定義數(shù)據(jù) df=pd.DataFrame({'x_values': range(1,11), 'y_values': np.random.randn(10) })# 初始化布局 fig = plt.figure(figsize=(12,3))# 自定義顏色 plt.subplot(1, 3, 1) plt.plot( 'x_values', 'y_values', data=df, color='skyblue') plt.title('自定義顏色')# 自定義透明度 plt.subplot(1, 3, 2) plt.plot( 'x_values', 'y_values', data=df, color='skyblue', alpha=0.3) plt.title('自定義透明度')# 自定義線條 plt.subplot(1, 3, 3) plt.plot( 'x_values', 'y_values', data=df, linestyle='dashed', linewidth=5) plt.title('自定義線條')plt.show()
-
帶注釋的折線圖
import matplotlib.pyplot as plt import numpy as np import pandas as pdplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽# 自定義數(shù)據(jù) dates = []for date in range(1970,2023):dates.append(str(date))sample_size = 2023-1970 variable = np.random.normal(100,15,sample_size,)df = pd.DataFrame({'date': dates,'value': variable})# 初始化布局 fig = plt.figure(figsize=(12,8))# 1-基本折線圖 plt.subplot(2, 1, 1) plt.plot(df['date'], df['value'])# 軸標簽 plt.xlabel('X-axis') plt.ylabel('Y-axis') plt.title('基本折線圖')# 刻度 plt.xticks(rotation=45)# 2-帶注釋的折線圖 plt.subplot(2, 1, 2) plt.plot(df['date'], df['value'])# 軸標簽 plt.xlabel('X-axis') plt.ylabel('Y-axis') plt.title('帶注釋的折線圖')# 刻度 plt.xticks(rotation=45)# 添加文本注釋 plt.text(df['date'].iloc[38], # x位置df['value'].iloc[1], # y位置'What a nice chart!', # 文本注釋fontsize=13,color='red')# 找到最大值索引 highest_index = df['value'].idxmax()# 最高值標記 plt.scatter(df['date'].iloc[highest_index],df['value'].iloc[highest_index],color='blue',marker='o', # 標記特殊的店s=100,)# 計算均值 median_value = df['value'].median()# 添加均值線 plt.axhline(y=median_value, color='green', linestyle='--', label='Reference Line (Median)')fig.tight_layout() # 自動調整間距 plt.show()
-
對數(shù)變換的折線圖
import matplotlib.pyplot as plt from matplotlib.ticker import MultipleLocator import numpy as np import pandas as pdplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽# 自定義數(shù)據(jù) x = np.linspace(1, 10, 100) y = np.exp(x) df = pd.DataFrame({'x': x, 'y': y})# 初始化布局 fig = plt.figure(figsize=(12,4))# 1-基本折線圖 plt.subplot(1, 2, 1) plt.plot(df['x'], df['y'])# 軸標簽 plt.xlabel('X-axis') plt.ylabel('Y-axis') plt.title('基本折線圖')# 添加網(wǎng)格線 plt.grid(True, linestyle='--', alpha=0.6)# 2-對數(shù)轉化折線圖 plt.subplot(1, 2, 2) plt.plot(df['x'], df['y'])# y軸對數(shù)化 plt.yscale('log')# 軸標簽 plt.xlabel('X-axis') plt.ylabel('Y-axis') plt.title('對數(shù)化的折線圖')# 對數(shù)刻度的網(wǎng)格 y_major_locator = MultipleLocator(3000) plt.gca().yaxis.set_major_locator(y_major_locator)# 添加網(wǎng)格線 plt.grid(True, linestyle='--', alpha=0.6)plt.show()
-
雙軸折線圖
import matplotlib.pyplot as plt import numpy as np from datetime import datetime, timedelta from matplotlib import colorsplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽rng = np.random.default_rng(1234)date = [datetime(2019, 1, 1) + timedelta(i) for i in range(100)] temperature = np.arange(100) ** 2.5 / 10000 + rng.uniform(size=100) price = np.arange(120, 20, -1) ** 1.5 / 10 + rng.uniform(size=100)# 設置多子圖 fig, axarr = plt.subplots(2, 2, figsize=(12, 8))# 1-基礎的雙軸折線圖 ax1 = axarr[0, 0] ax2 = ax1.twinx() ax1.plot(date, temperature) ax2.plot(date, price) ax1.set_title('基礎的雙軸折線圖')# 2-自定義顏色雙軸 COLOR_TEMPERATURE = "#69b3a2" COLOR_PRICE = "#3399e6"ax1 = axarr[0, 1] ax2 = ax1.twinx() ax1.plot(date, temperature, color=COLOR_TEMPERATURE, lw=3) ax2.plot(date, price, color=COLOR_PRICE, lw=4)ax1.set_xlabel("Date") ax1.set_ylabel("Temperature (Celsius °)", color=COLOR_TEMPERATURE, fontsize=14) ax1.tick_params(axis="y", labelcolor=COLOR_TEMPERATURE) ax2.set_ylabel("Price ($)", color=COLOR_PRICE, fontsize=14) ax2.tick_params(axis="y", labelcolor=COLOR_PRICE) ax1.set_title('自定義顏色雙軸')# 3-折線與條形圖組合 ax1 = axarr[1, 0] ax2 = ax1.twinx() ax1.bar(date, temperature, color=COLOR_TEMPERATURE, edgecolor="black", alpha=0.4, width=1.0) ax2.plot(date, price, color=COLOR_PRICE, lw=4)ax1.set_xlabel("Date") ax1.set_ylabel("Temperature (Celsius °)", color=COLOR_TEMPERATURE, fontsize=14) ax1.tick_params(axis="y", labelcolor=COLOR_TEMPERATURE)ax2.set_ylabel("Price ($)", color=COLOR_PRICE, fontsize=14) ax2.tick_params(axis="y", labelcolor=COLOR_PRICE)fig.autofmt_xdate() ax1.set_title("折線與條形圖組合")# 4-自定義組合圖樣式 color = list(colors.to_rgba(COLOR_TEMPERATURE)) color[3] = 0.4ax1 = axarr[1, 1] ax2 = ax1.twinx() ax1.bar(date, temperature, color=color, edgecolor="black", width=1.0) ax2.plot(date, price, color=COLOR_PRICE, lw=4)ax1.set_xlabel("Date") ax1.set_ylabel("Temperature (Celsius °)", color=COLOR_TEMPERATURE, fontsize=14) ax1.tick_params(axis="y", labelcolor=COLOR_TEMPERATURE)ax2.set_ylabel("Price ($)", color=COLOR_PRICE, fontsize=14) ax2.tick_params(axis="y", labelcolor=COLOR_PRICE)fig.autofmt_xdate() ax1.set_title("自定義組合圖樣式")fig.tight_layout() # 自動調整間距 plt.show()
-
多個折線圖
import matplotlib.pyplot as plt import numpy as np from datetime import datetime, timedelta from matplotlib import colors import matplotlib.gridspec as gridspecplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽# 創(chuàng)建 2x3 的大布局 fig = plt.figure(figsize=(18, 8)) gs = gridspec.GridSpec(2, 3, figure=fig) # 獲得每個子圖的位置 ax1 = fig.add_subplot(gs[0, 0]) ax2 = fig.add_subplot(gs[0, 1]) ax3 = fig.add_subplot(gs[0, 2]) # ax4 = fig.add_subplot(gs[1, 0]) # ax5 = fig.add_subplot(gs[1, 1]) ax6 = fig.add_subplot(gs[1, 2])# 1-基礎的多折線圖 df=pd.DataFrame({'x_values': range(1,11), 'y1_values': np.random.randn(10), 'y2_values': np.random.randn(10)+range(1,11), 'y3_values': np.random.randn(10)+range(11,21) })ax1.plot( 'x_values', 'y1_values', data=df, marker='o', markerfacecolor='blue', markersize=12, color='skyblue', linewidth=4) ax1.plot( 'x_values', 'y2_values', data=df, marker='', color='olive', linewidth=2) ax1.plot( 'x_values', 'y3_values', data=df, marker='', color='olive', linewidth=2, linestyle='dashed', label="toto") ax1.legend() ax1.set_title('基礎的多折線圖')# 2-高亮顯示一組 df=pd.DataFrame({'x': range(1,11), 'y1': np.random.randn(10), 'y2': np.random.randn(10)+range(1,11), 'y3': np.random.randn(10)+range(11,21), 'y4': np.random.randn(10)+range(6,16), 'y5': np.random.randn(10)+range(4,14)+(0,0,0,0,0,0,0,-3,-8,-6), 'y6': np.random.randn(10)+range(2,12), 'y7': np.random.randn(10)+range(5,15), 'y8': np.random.randn(10)+range(4,14) })for column in df.drop('x', axis=1):ax2.plot(df['x'], df[column], marker='', color='grey', linewidth=1, alpha=0.4) ax2.plot(df['x'], df['y5'], marker='', color='orange', linewidth=4, alpha=0.7) # 高亮y5 ax2.set_xlim(0,12) # 增加注釋 num=0 for i in df.values[9][1:]:num+=1name=list(df)[num]if name != 'y5':ax2.text(10.2, i, name, horizontalalignment='left', size='small', color='grey')else:ax2.text(10.2, i, 'Mr Orange', horizontalalignment='left', size='small', color='orange') # 高亮組的文本注釋 ax2.set_title("高亮顯示一組")# 3-多折線模式(Spaghetti Plot) df=pd.DataFrame({'x': range(1,11), 'y1': np.random.randn(10), 'y2': np.random.randn(10)+range(1,11), 'y3': np.random.randn(10)+range(11,21), 'y4': np.random.randn(10)+range(6,16), 'y5': np.random.randn(10)+range(4,14)+(0,0,0,0,0,0,0,-3,-8,-6), 'y6': np.random.randn(10)+range(2,12), 'y7': np.random.randn(10)+range(5,15), 'y8': np.random.randn(10)+range(4,14), 'y9': np.random.randn(10)+range(4,14), 'y10': np.random.randn(10)+range(2,12) })palette = plt.get_cmap('Set1') num=0 for column in df.drop('x', axis=1):num+=1ax3.plot(df['x'], df[column], marker='', color=palette(num), linewidth=1, alpha=0.9, label=column)ax3.legend(loc=2, ncol=2) ax3.set_title("多折線模式(Spaghetti Plot)")# 4-多折線小圖 df=pd.DataFrame({'x': range(1,11), 'y1': np.random.randn(10), 'y2': np.random.randn(10)+range(1,11), 'y3': np.random.randn(10)+range(11,21), 'y4': np.random.randn(10)+range(6,16), 'y5': np.random.randn(10)+range(4,14)+(0,0,0,0,0,0,0,-3,-8,-6), 'y6': np.random.randn(10)+range(2,12), 'y7': np.random.randn(10)+range(5,15), 'y8': np.random.randn(10)+range(4,14), 'y9': np.random.randn(10)+range(4,14) }) # 在第一行第一列的位置創(chuàng)建3*3的子布局 ax4 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs[1, 0]) # 在 3x3 的小布局中添加子圖 axes = [] for i in range(3):for j in range(3):ax = fig.add_subplot(ax4[i, j])axes.append(ax) # 將子圖句柄添加到列表中 num = 0 for column in df.drop('x', axis=1):num += 1ax = axes[num - 1]ax.plot(df['x'], df[column], marker='', color=palette(num), linewidth=1.9, alpha=0.9, label=column)ax.set_xlim(0,10)ax.set_ylim(-2,22)# 如果當前子圖不在最左邊,就不顯示y軸的刻度標簽if num not in [1,4,7] :ax.tick_params(labelleft=False)# 如果當前子圖不在最下邊,就不顯示x軸的刻度標簽if num not in [7,8,9] :ax.tick_params(labelbottom=False)ax.annotate(column, xy=(0, 1), xycoords='axes fraction', fontsize=12, fontweight=0, color=palette(num),xytext=(5, -5), textcoords='offset points', ha='left', va='top')axes[1].set_title('多折線小圖') # 通過設置3*3圖的第二個子圖的標題替代2*3圖中的第4個圖的子標題# 5-多折線小圖細節(jié)處理 df=pd.DataFrame({'x': range(1,11), 'y1': np.random.randn(10), 'y2': np.random.randn(10)+range(1,11), 'y3': np.random.randn(10)+range(11,21), 'y4': np.random.randn(10)+range(6,16), 'y5': np.random.randn(10)+range(4,14)+(0,0,0,0,0,0,0,-3,-8,-6), 'y6': np.random.randn(10)+range(2,12), 'y7': np.random.randn(10)+range(5,15), 'y8': np.random.randn(10)+range(4,14), 'y9': np.random.randn(10)+range(4,14) }) # 在第一行第一列的位置創(chuàng)建3*3的子布局 ax5 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs[1, 1]) # 在 3x3 的小布局中添加子圖 axes = [] for i in range(3):for j in range(3):ax = fig.add_subplot(ax5[i, j])axes.append(ax) # 將子圖句柄添加到列表中 num=0 for column in df.drop('x', axis=1):num+=1ax = axes[num - 1]for v in df.drop('x', axis=1):ax.plot(df['x'], df[v], marker='', color='grey', linewidth=0.6, alpha=0.3)ax.plot(df['x'], df[column], marker='', color=palette(num), linewidth=2.4, alpha=0.9, label=column)ax.set_xlim(0,10)ax.set_ylim(-2,22)# 如果當前子圖不在最左邊,就不顯示y軸的刻度標簽if num not in [1,4,7] :ax.tick_params(labelleft=False)# 如果當前子圖不在最下邊,就不顯示x軸的刻度標簽if num not in [7,8,9] :ax.tick_params(labelbottom=False)ax.annotate(column, xy=(0, 1), xycoords='axes fraction', fontsize=12, fontweight=0, color=palette(num),xytext=(5, -5), textcoords='offset points', ha='left', va='top')axes[1].set_title('多折線小圖細節(jié)處理') # 通過設置3*3圖的第二個子圖的標題替代2*3圖中的第5個圖的子標題# 6-帶區(qū)域填充的多折線圖 time = np.arange(12) income = np.array([5, 9, 6, 6, 10, 7, 6, 4, 4, 5, 6, 4]) expenses = np.array([6, 6, 8, 3, 6, 9, 7, 8, 6, 6, 4, 8])ax6.plot(time, income, color="green") ax6.plot(time, expenses, color="red")# 當income > expenses填充綠色 ax6.fill_between(time, income, expenses, where=(income > expenses), interpolate=True, color="green", alpha=0.25, label="Positive" )# 當income <= expenses填充紅色 ax6.fill_between(time, income, expenses, where=(income <= expenses), interpolate=True, color="red", alpha=0.25,label="Negative" )ax6.set_title('帶區(qū)域填充的多折線圖') ax6.legend()plt.tight_layout() # 自動調整間距 plt.show()
-
繪制時間序列圖
import matplotlib.pyplot as plt import pandas as pd import matplotlib.dates as mdates# 導入數(shù)據(jù) data = pd.read_csv("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/3_TwoNumOrdered.csv", delim_whitespace=True )# 日期格式 data["date"] = pd.to_datetime(data["date"])date = data["date"] value = data["value"]# 繪制時間序列圖 fig, ax = plt.subplots(figsize=(8, 6))# 設置6個月間隔為一刻度 half_year_locator = mdates.MonthLocator(interval=6) # 半年刻度 monthly_locator = mdates.MonthLocator() # 每月子刻度 year_month_formatter = mdates.DateFormatter("%Y-%m") # 格式化日期yyyy-MMax.xaxis.set_major_locator(half_year_locator) ax.xaxis.set_minor_locator(monthly_locator) ax.xaxis.set_major_formatter(year_month_formatter)ax.plot(date, value)fig.autofmt_xdate() # 自動旋轉軸標簽
通過plotly繪制多樣化的折線圖
import plotly.graph_objects as go
import numpy as np
import pandas as pd# 自定義數(shù)據(jù)dates = []
start = 1990
end = 2022
for date in range(start,end):dates.append(str(date))# 生成隨機序列,并計算累計和來生成隨機漫步1、2、3
random_steps = np.random.choice([-1, 1], size=end-start, p=[0.5, 0.5])
random_walk1 = np.cumsum(random_steps)random_steps = np.random.choice([-1, 1], size=end-start, p=[0.5, 0.5])
random_walk2 = np.cumsum(random_steps)random_steps = np.random.choice([-1, 1], size=end-start, p=[0.5, 0.5])
random_walk3 = np.cumsum(random_steps)# 具有三個隨機漫步的數(shù)據(jù)
df = pd.DataFrame({'date': dates,'value1': random_walk1,'value2': random_walk2,'value3': random_walk3,})fig = go.Figure()# 自定義變量1
fig.add_trace(go.Scatter(x=df['date'],y=df['value1'],mode='lines+markers', # 點線連接樣式name='Line1',marker=dict(symbol='square', size=10, color='red'), line=dict(color='blue', width=5)
))# 自定義變量2
fig.add_trace(go.Scatter(x=df['date'], y=df['value2'], mode='lines+markers', name='Line2', marker=dict(symbol='circle', size=7, color='purple'), line=dict(color='orange', width=8)
))# 自定義變量3
fig.add_trace(go.Scatter(x=df['date'], y=df['value3'], mode='lines+markers', name='Line3',marker=dict(symbol='diamond', size=15, color='yellow'), line=dict(color='green', width=4)
))# 自定義布局
fig.update_layout(title='Customized Line Chart',xaxis_title='X Axis Label', yaxis_title='Y Axis Label',xaxis_tickangle=45, showlegend=True, plot_bgcolor='white', paper_bgcolor='lightblue',
)
通過pandas繪制多樣化的折線圖
-
修改參數(shù)
import pandas as pd import matplotlib.pyplot as plt# 導入數(shù)據(jù) url = 'https://raw.githubusercontent.com/holtzy/The-Python-Graph-Gallery/master/static/data/gapminderData.csv' df = pd.read_csv(url) df_france = df[df['country']=='France']# 繪制折線圖 ax = df_france.plot(x='year',y='lifeExp',grid=True,linestyle='--',alpha=0.5,color='purple',linewidth=2.0, marker='d', markersize=8, markerfacecolor='orange', label='France')# 標題 ax.set_title('Evolution of \nthe life expectancy in France',weight='bold') # 軸標簽 ax.set_ylabel('Life Expectancy') ax.set_xlabel('Time (in year)')plt.show()
-
多變量折線圖
import pandas as pd import random, numpy as np import matplotlib.pyplot as plt# 自定義數(shù)據(jù) num_time_points = 100 time_values = np.arange(num_time_points)temperature = np.random.uniform(200, 400, num_time_points) pressure = np.random.uniform(500, 700, num_time_points) humidity = np.random.uniform(800, 1000, num_time_points) data = {'Time': time_values,'Temperature': temperature,'Pressure': pressure,'Humidity': humidity } df = pd.DataFrame(data)# 繪制多變量折線圖 df.plot(x='Time',kind='line', grid=True, ) plt.legend(loc='upper right',bbox_to_anchor=(1.35, 1), ) plt.show()
-
分組折線圖
import pandas as pd import random, numpy as np import matplotlib.pyplot as plt# 自定義數(shù)據(jù) num_data_points_per_country = 20# 設置多個國家的溫度 france_temperatures = np.random.uniform(10, 20, num_data_points_per_country) germany_temperatures = np.random.uniform(0, 10, num_data_points_per_country) italy_temperatures = np.random.uniform(25, 30, num_data_points_per_country) # 對應的國家數(shù)據(jù) countries = ['France', 'Germany', 'Italy'] country_labels = np.repeat(countries, num_data_points_per_country)# 時間數(shù)據(jù) time_values = np.tile(np.arange(num_data_points_per_country), len(countries))data = {'Country': country_labels,'Temperature': np.concatenate([france_temperatures, germany_temperatures, italy_temperatures]),'Time': time_values }df = pd.DataFrame(data)# 繪制折線圖 for name, group in df.groupby('Country'):plt.plot(group['Time'], group['Temperature'], label=name)# 設置圖表的標題和坐標軸標簽,并顯示圖例 plt.title('Temperature Trend over Time by Country') plt.xlabel('Time') plt.ylabel('Temperature') plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')# 顯示圖表 plt.show()
總結
以上通過matplotlib、seaborn、plotly和pandas快速繪制折線圖。并通過修改參數(shù)或者輔以其他繪圖知識自定義各種各樣的折線圖來適應相關使用場景。
共勉~