幾行代碼完成動態圖表繪製|Python實戰

2020-12-05 AI科技大本營

作者 | 小F

來源 | 法納斯特

頭圖 | CSDN下載自視覺中國

關於動態條形圖,小F以前推薦過「Bar Chart Race」這個庫。三行代碼就能實現動態條形圖的繪製。

有些同學在使用的時候,會出現一些錯誤。一個是加載文件報錯,另一個是生成GIF的時候報錯。

這是因為作者的示例是網絡加載數據,會讀取不到。通過讀取本地文件,就不會出錯。

GIF生成失敗一般是需要安裝imagemagick(圖片處理工具)。

最近小F又發現一個可視化圖庫「Pandas_Alive」,不僅包含動態條形圖,還可以繪製動態曲線圖、氣泡圖、餅狀圖、地圖等。

同樣也是幾行代碼就能完成動態圖表的繪製。

安裝版本建議是0.2.3,matplotlib版本是3.2.1。

同時需自行安裝tqdm(顯示進度條)和descartes(繪製地圖相關庫)。

要不然會出現報錯,估計是作者的requestment.txt沒包含這兩個庫。

好了,成功安裝後就可以引入這個第三方庫,直接選擇加載本地文件。

import pandas_aliveimport pandas as pdcovid_df = pd.read_csv('data/covid19.csv', index_col=0, parse_dates=[0])covid_df.plot_animated(filename='examples/example-barh-chart.gif', n_visible=15)生成了一個GIF圖,具體如下。

剛開始學習這個庫的時候,大家可以減少數據,這樣生成GIF的時間就會快一些。

比如小F在接下來的實踐中,基本都只選取了20天左右的數據。

對於其他圖表,我們可以查看官方文檔的API說明,得以了解。

下面我們就來看看其他動態圖表的繪製方法吧!

動態條形圖

elec_df = pd.read_csv("data/Aus_Elec_Gen_1980_2018.csv", index_col=0, parse_dates=[0], thousands=',')elec_df = elec_df.iloc[:20, :]elec_df.fillna(0).plot_animated('examples/example-electricity-generated-australia.gif', period_fmt="%Y", title='Australian Electricity Generation Sources 1980-2018')

動態柱狀圖

covid_df = pd.read_csv('data/covid19.csv', index_col=0, parse_dates=[0])covid_df.plot_animated(filename='examples/example-barv-chart.gif', orientation='v', n_visible=15)

動態曲線圖

covid_df = pd.read_csv('data/covid19.csv', index_col=0, parse_dates=[0])covid_df.diff.fillna(0).plot_animated(filename='examples/example-line-chart.gif', kind='line', period_label={'x': 0.25, 'y': 0.9})

動態面積圖

covid_df = pd.read_csv('data/covid19.csv', index_col=0, parse_dates=[0])covid_df.sum(axis=1).fillna(0).plot_animated(filename='examples/example-bar-chart.gif', kind='bar', period_label={'x': 0.1, 'y': 0.9}, enable_progress_bar=True, steps_per_period=2, interpolate_period=True, period_length=200)

動態散點圖

max_temp_df = pd.read_csv("data/Newcastle_Australia_Max_Temps.csv", parse_dates={"Timestamp": ["Year", "Month", "Day"]},)min_temp_df = pd.read_csv("data/Newcastle_Australia_Min_Temps.csv", parse_dates={"Timestamp": ["Year", "Month", "Day"]},)

max_temp_df = max_temp_df.iloc[:5000, :]min_temp_df = min_temp_df.iloc[:5000, :]

merged_temp_df = pd.merge_asof(max_temp_df, min_temp_df, on="Timestamp")merged_temp_df.index = pd.to_datetime(merged_temp_df["Timestamp"].dt.strftime('%Y/%m/%d'))

keep_columns = ["Minimum temperature (Degree C)", "Maximum temperature (Degree C)"]merged_temp_df[keep_columns].resample("Y").mean.plot_animated(filename='examples/example-scatter-chart.gif', kind="scatter", title='Max & Min Temperature Newcastle, Australia')

動態餅狀圖

covid_df = pd.read_csv('data/covid19.csv', index_col=0, parse_dates=[0])covid_df.plot_animated(filename='examples/example-pie-chart.gif', kind="pie", rotatelabels=True, period_label={'x': 0, 'y': 0})

動態氣泡圖

multi_index_df = pd.read_csv("data/multi.csv", header=[0, 1], index_col=0)multi_index_df.index = pd.to_datetime(multi_index_df.index, dayfirst=True)

map_chart = multi_index_df.plot_animated( kind="bubble", filename="examples/example-bubble-chart.gif", x_data_label="Longitude", y_data_label="Latitude", size_data_label="Cases", color_data_label="Cases", vmax=5, steps_per_period=3, interpolate_period=True, period_length=500, dpi=100)

地理空間點圖表

import geopandasimport pandas_aliveimport contextily

gdf = geopandas.read_file('data/nsw-covid19-cases-by-postcode.gpkg')gdf.index = gdf.postcodegdf = gdf.drop('postcode',axis=1)

result = gdf.iloc[:, :20]result['geometry'] = gdf.iloc[:, -1:]['geometry']

map_chart = result.plot_animated(filename='examples/example-geo-point-chart.gif', basemap_format={'source':contextily.providers.Stamen.Terrain})

多邊形地理圖表

import geopandasimport pandas_aliveimport contextily

gdf = geopandas.read_file('data/italy-covid-region.gpkg')gdf.index = gdf.regiongdf = gdf.drop('region',axis=1)

result = gdf.iloc[:, :20]result['geometry'] = gdf.iloc[:, -1:]['geometry']

map_chart = result.plot_animated(filename='examples/example-geo-polygon-chart.gif', basemap_format={'source': contextily.providers.Stamen.Terrain})

多個動態圖表

covid_df = pd.read_csv('data/covid19.csv', index_col=0, parse_dates=[0])

animated_line_chart = covid_df.diff.fillna(0).plot_animated(kind='line', period_label=False,add_legend=False)animated_bar_chart = covid_df.plot_animated(n_visible=10)

pandas_alive.animate_multiple_plots('examples/example-bar-and-line-chart.gif', [animated_bar_chart, animated_line_chart], enable_progress_bar=True)

城市人口

def population: urban_df = pd.read_csv("data/urban_pop.csv", index_col=0, parse_dates=[0])

animated_line_chart = ( urban_df.sum(axis=1) .pct_change .fillna(method='bfill') .mul(100) .plot_animated(kind="line", title="Total % Change in Population", period_label=False, add_legend=False) )

animated_bar_chart = urban_df.plot_animated(n_visible=10, title='Top 10 Populous Countries', period_fmt="%Y")

pandas_alive.animate_multiple_plots('examples/example-bar-and-line-urban-chart.gif', [animated_bar_chart, animated_line_chart], title='Urban Population 1977 - 2018', adjust_subplot_top=0.85, enable_progress_bar=True)

G7國家平均壽命

def life: data_raw = pd.read_csv("data/long.csv")

list_G7 = ["Canada","France","Germany","Italy","Japan","United Kingdom","United States", ]

data_raw = data_raw.pivot( index="Year", columns="Entity", values="Life expectancy (Gapminder, UN)" )

data = pd.DataFramedata["Year"] = data_raw.reset_index["Year"]for country in list_G7:data[country] = data_raw[country].values

data = data.fillna(method="pad")data = data.fillna(0)data = data.set_index("Year").loc[1900:].reset_index

data["Year"] = pd.to_datetime(data.reset_index["Year"].astype(str))

data = data.set_index("Year")data = data.iloc[:25, :]

animated_bar_chart = data.plot_animated( period_fmt="%Y", perpendicular_bar_func="mean", period_length=200, fixed_max=True )

animated_line_chart = data.plot_animated( kind="line", period_fmt="%Y", period_length=200, fixed_max=True )

pandas_alive.animate_multiple_plots("examples/life-expectancy.gif", plots=[animated_bar_chart, animated_line_chart], title="Life expectancy in G7 countries up to 2015", adjust_subplot_left=0.2, adjust_subplot_top=0.9, enable_progress_bar=True )

新南威爾斯州COVID可視化

def nsw:import geopandasimport pandas as pdimport pandas_aliveimport contextilyimport matplotlib.pyplot as pltimport json

with open('data/package_show.json', 'r', encoding='utf8')as fp: data = json.load(fp)

# Extract url to csv component covid_nsw_data_url = data["result"]["resources"][0]["url"] print(covid_nsw_data_url)

# Read csv from data API url nsw_covid = pd.read_csv('data/confirmed_cases_table1_location.csv') postcode_dataset = pd.read_csv("data/postcode-data.csv")

# Prepare data from NSW health dataset

nsw_covid = nsw_covid.fillna(9999) nsw_covid["postcode"] = nsw_covid["postcode"].astype(int)

grouped_df = nsw_covid.groupby(["notification_date", "postcode"]).size grouped_df = pd.DataFrame(grouped_df).unstack grouped_df.columns = grouped_df.columns.droplevel.astype(str)

grouped_df = grouped_df.fillna(0) grouped_df.index = pd.to_datetime(grouped_df.index)

cases_df = grouped_df

# Clean data in postcode dataset prior to matching

grouped_df = grouped_df.T postcode_dataset = postcode_dataset[postcode_dataset['Longitude'].notna] postcode_dataset = postcode_dataset[postcode_dataset['Longitude'] != 0] postcode_dataset = postcode_dataset[postcode_dataset['Latitude'].notna] postcode_dataset = postcode_dataset[postcode_dataset['Latitude'] != 0] postcode_dataset['Postcode'] = postcode_dataset['Postcode'].astype(str)

# Build GeoDataFrame from Lat Long dataset and make map chart grouped_df['Longitude'] = grouped_df.index.map(postcode_dataset.set_index('Postcode')['Longitude'].to_dict) grouped_df['Latitude'] = grouped_df.index.map(postcode_dataset.set_index('Postcode')['Latitude'].to_dict) gdf = geopandas.GeoDataFrame( grouped_df, geometry=geopandas.points_from_xy(grouped_df.Longitude, grouped_df.Latitude), crs="EPSG:4326") gdf = gdf.dropna

# Prepare GeoDataFrame for writing to geopackage gdf = gdf.drop(['Longitude', 'Latitude'], axis=1) gdf.columns = gdf.columns.astype(str) gdf['postcode'] = gdf.index# gdf.to_file("data/nsw-covid19-cases-by-postcode.gpkg", layer='nsw-postcode-covid', driver="GPKG")

# Prepare GeoDataFrame for plotting gdf.index = gdf.postcode gdf = gdf.drop('postcode', axis=1) gdf = gdf.to_crs("EPSG:3857") # Web Mercator

result = gdf.iloc[:, :22] result['geometry'] = gdf.iloc[:, -1:]['geometry'] gdf = result

map_chart = gdf.plot_animated(basemap_format={'source': contextily.providers.Stamen.Terrain}, cmap='cool')

# cases_df.to_csv('data/nsw-covid-cases-by-postcode.csv') cases_df = cases_df.iloc[:22, :]

from datetime import datetime

bar_chart = cases_df.sum(axis=1).plot_animated( kind='line', label_events={'Ruby Princess Disembark': datetime.strptime("19/03/2020", "%d/%m/%Y"),# 'Lockdown': datetime.strptime("31/03/2020", "%d/%m/%Y") }, fill_under_line_color="blue", add_legend=False )

map_chart.ax.set_title('Cases by Location')

grouped_df = pd.read_csv('data/nsw-covid-cases-by-postcode.csv', index_col=0, parse_dates=[0]) grouped_df = grouped_df.iloc[:22, :]

line_chart = ( grouped_df.sum(axis=1) .cumsum .fillna(0) .plot_animated(kind="line", period_label=False, title="Cumulative Total Cases", add_legend=False) )

def current_total(values): total = values.sum s = f'Total : {int(total)}'return {'x': .85, 'y': .2, 's': s, 'ha': 'right', 'size': 11}

race_chart = grouped_df.cumsum.plot_animated( n_visible=5, title="Cases by Postcode", period_label=False, period_summary_func=current_total )

import time

timestr = time.strftime("%d/%m/%Y")

plots = [bar_chart, line_chart, map_chart, race_chart]

from matplotlib import rcParams

rcParams.update({"figure.autolayout": False})# make sure figures are `Figure` instances figs = plt.Figure gs = figs.add_gridspec(2, 3, hspace=0.5) f3_ax1 = figs.add_subplot(gs[0, :]) f3_ax1.set_title(bar_chart.title) bar_chart.ax = f3_ax1

f3_ax2 = figs.add_subplot(gs[1, 0]) f3_ax2.set_title(line_chart.title) line_chart.ax = f3_ax2

f3_ax3 = figs.add_subplot(gs[1, 1]) f3_ax3.set_title(map_chart.title) map_chart.ax = f3_ax3

f3_ax4 = figs.add_subplot(gs[1, 2]) f3_ax4.set_title(race_chart.title) race_chart.ax = f3_ax4

timestr = cases_df.index.max.strftime("%d/%m/%Y") figs.suptitle(f"NSW COVID-19 Confirmed Cases up to {timestr}")

pandas_alive.animate_multiple_plots('examples/nsw-covid.gif', plots, figs, enable_progress_bar=True )

義大利COVID可視化

def italy:import geopandasimport pandas as pdimport pandas_aliveimport contextilyimport matplotlib.pyplot as plt

region_gdf = geopandas.read_file('data/geo-data/italy-with-regions') region_gdf.NOME_REG = region_gdf.NOME_REG.str.lower.str.title region_gdf = region_gdf.replace('Trentino-Alto Adige/Sudtirol', 'Trentino-Alto Adige') region_gdf = region_gdf.replace("Valle D'Aosta/Valle D'Aoste\r\nValle D'Aosta/Valle D'Aoste", "Valle d'Aosta")

italy_df = pd.read_csv('data/Regional Data - Sheet1.csv', index_col=0, header=1, parse_dates=[0])

italy_df = italy_df[italy_df['Region'] != 'NA']

cases_df = italy_df.iloc[:, :3] cases_df['Date'] = cases_df.index pivoted = cases_df.pivot(values='New positives', index='Date', columns='Region') pivoted.columns = pivoted.columns.astype(str) pivoted = pivoted.rename(columns={'nan': 'Unknown Region'})

cases_gdf = pivoted.T cases_gdf['geometry'] = cases_gdf.index.map(region_gdf.set_index('NOME_REG')['geometry'].to_dict)

cases_gdf = cases_gdf[cases_gdf['geometry'].notna]

cases_gdf = geopandas.GeoDataFrame(cases_gdf, crs=region_gdf.crs, geometry=cases_gdf.geometry)

gdf = cases_gdf

result = gdf.iloc[:, :22] result['geometry'] = gdf.iloc[:, -1:]['geometry'] gdf = result

map_chart = gdf.plot_animated(basemap_format={'source': contextily.providers.Stamen.Terrain}, cmap='viridis')

cases_df = pivoted cases_df = cases_df.iloc[:22, :]

from datetime import datetime

bar_chart = cases_df.sum(axis=1).plot_animated( kind='line', label_events={'Schools Close': datetime.strptime("4/03/2020", "%d/%m/%Y"),'Phase I Lockdown': datetime.strptime("11/03/2020", "%d/%m/%Y"),# '1M Global Cases': datetime.strptime("02/04/2020", "%d/%m/%Y"),# '100k Global Deaths': datetime.strptime("10/04/2020", "%d/%m/%Y"),# 'Manufacturing Reopens': datetime.strptime("26/04/2020", "%d/%m/%Y"),# 'Phase II Lockdown': datetime.strptime("4/05/2020", "%d/%m/%Y"), }, fill_under_line_color="blue", add_legend=False )

map_chart.ax.set_title('Cases by Location')

line_chart = ( cases_df.sum(axis=1) .cumsum .fillna(0) .plot_animated(kind="line", period_label=False, title="Cumulative Total Cases", add_legend=False) )

def current_total(values): total = values.sum s = f'Total : {int(total)}'return {'x': .85, 'y': .1, 's': s, 'ha': 'right', 'size': 11}

race_chart = cases_df.cumsum.plot_animated( n_visible=5, title="Cases by Region", period_label=False, period_summary_func=current_total )

import time

timestr = time.strftime("%d/%m/%Y")

plots = [bar_chart, race_chart, map_chart, line_chart]

# Otherwise titles overlap and adjust_subplot does nothingfrom matplotlib import rcParamsfrom matplotlib.animation import FuncAnimation

rcParams.update({"figure.autolayout": False})# make sure figures are `Figure` instances figs = plt.Figure gs = figs.add_gridspec(2, 3, hspace=0.5) f3_ax1 = figs.add_subplot(gs[0, :]) f3_ax1.set_title(bar_chart.title) bar_chart.ax = f3_ax1

f3_ax2 = figs.add_subplot(gs[1, 0]) f3_ax2.set_title(race_chart.title) race_chart.ax = f3_ax2

f3_ax3 = figs.add_subplot(gs[1, 1]) f3_ax3.set_title(map_chart.title) map_chart.ax = f3_ax3

f3_ax4 = figs.add_subplot(gs[1, 2]) f3_ax4.set_title(line_chart.title) line_chart.ax = f3_ax4

axes = [f3_ax1, f3_ax2, f3_ax3, f3_ax4] timestr = cases_df.index.max.strftime("%d/%m/%Y") figs.suptitle(f"Italy COVID-19 Confirmed Cases up to {timestr}")

pandas_alive.animate_multiple_plots('examples/italy-covid.gif', plots, figs, enable_progress_bar=True )

單擺運動

def simple:import pandas as pdimport matplotlib.pyplot as pltimport pandas_aliveimport numpy as np

# Physical constants g = 9.81 L = .4 mu = 0.2

THETA_0 = np.pi * 70 / 180 # init angle = 70degs THETA_DOT_0 = 0 # no init angVel DELTA_T = 0.01 # time stepping T = 1.5 # time period

# Definition of ODE (ordinary differential equation)def get_theta_double_dot(theta, theta_dot):return -mu * theta_dot - (g / L) * np.sin(theta)

# Solution to the differential equationdef pendulum(t):# initialise changing values theta = THETA_0 theta_dot = THETA_DOT_0 delta_t = DELTA_T ang = ang_vel = ang_acc = times = for time in np.arange(0, t, delta_t): theta_double_dot = get_theta_double_dot( theta, theta_dot ) theta += theta_dot * delta_t theta_dot += theta_double_dot * delta_t times.append(time) ang.append(theta) ang_vel.append(theta_dot) ang_acc.append(theta_double_dot) data = np.array([ang, ang_vel, ang_acc])return pd.DataFrame(data=data.T, index=np.array(times), columns=["angle", "ang_vel", "ang_acc"])

# units used for ref: ["angle [rad]", "ang_vel [rad/s]", "ang_acc [rad/s^2]"] df = pendulum(T) df.index.names = ["Time (s)"] print(df)

# generate dataFrame for animated bubble plot df2 = pd.DataFrame(index=df.index) df2["dx (m)"] = L * np.sin(df["angle"]) df2["dy (m)"] = -L * np.cos(df["angle"]) df2["ang_vel"] = abs(df["ang_vel"]) df2["size"] = df2["ang_vel"] * 100 # scale angular vels to get nice size on bubble plot print(df2)

# static pandas plots## print(plt.style.available)# NOTE: 2 lines below required in Jupyter to switch styles correctly plt.rcParams.update(plt.rcParamsDefault) plt.style.use("ggplot") # set plot style

fig, (ax1a, ax2b) = plt.subplots(1, 2, figsize=(8, 4), dpi=100) # 1 row, 2 subplots# fig.subplots_adjust(wspace=0.1) # space subplots in row fig.set_tight_layout(True) fontsize = "small"

df.plot(ax=ax1a).legend(fontsize=fontsize) ax1a.set_title("Outputs vs Time", fontsize="medium") ax1a.set_xlabel('Time [s]', fontsize=fontsize) ax1a.set_ylabel('Amplitudes', fontsize=fontsize);

df.plot(ax=ax2b, x="angle", y=["ang_vel", "ang_acc"]).legend(fontsize=fontsize) ax2b.set_title("Outputs vs Angle | Phase-Space", fontsize="medium") ax2b.set_xlabel('Angle [rad]', fontsize=fontsize) ax2b.set_ylabel('Angular Velocity / Acc', fontsize=fontsize)

# sample scatter plot with colorbar fig, ax = plt.subplots sc = ax.scatter(df2["dx (m)"], df2["dy (m)"], s=df2["size"] * .1, c=df2["ang_vel"], cmap="jet") cbar = fig.colorbar(sc) cbar.set_label(label="ang_vel [rad/s]", fontsize="small")# sc.set_clim(350, 400) ax.tick_params(labelrotation=0, labelsize="medium") ax_scale = 1. ax.set_xlim(-L * ax_scale, L * ax_scale) ax.set_ylim(-L * ax_scale - 0.1, L * ax_scale - 0.1)# make axes square: a circle shows as a circle ax.set_aspect(1 / ax.get_data_ratio) ax.arrow(0, 0, df2["dx (m)"].iloc[-1], df2["dy (m)"].iloc[-1], color="dimgray", ls=":", lw=2.5, width=.0, head_width=0, zorder=-1 ) ax.text(0, 0.15, s="size and colour of pendulum bob\nbased on pd column\nfor angular velocity", ha='center', va='center')

# plt.show

dpi = 100 ax_scale = 1.1 figsize = (3, 3) fontsize = "small"

# set up figure to pass onto `pandas_alive`# NOTE: by using Figure (capital F) instead of figure `FuncAnimation` seems to run twice as fast!# fig1, ax1 = plt.subplots fig1 = plt.Figure ax1 = fig1.add_subplot fig1.set_size_inches(figsize) ax1.set_title("Simple pendulum animation, L=" + str(L) + "m", fontsize="medium") ax1.set_xlabel("Time (s)", color='dimgray', fontsize=fontsize) ax1.set_ylabel("Amplitudes", color='dimgray', fontsize=fontsize) ax1.tick_params(labelsize=fontsize)

# pandas_alive line_chart = df.plot_animated(filename="pend-line.gif", kind='line', period_label={'x': 0.05, 'y': 0.9}, steps_per_period=1, interpolate_period=False, period_length=50, period_fmt='Time:{x:10.2f}', enable_progress_bar=True, fixed_max=True, dpi=100, fig=fig1 ) plt.close

# Video('examples/pend-line.mp4', html_attributes="controls muted autoplay")

# set up and generate animated scatter plot#

# set up figure to pass onto `pandas_alive`# NOTE: by using Figure (capital F) instead of figure `FuncAnimation` seems to run twice as fast! fig1sc = plt.Figure ax1sc = fig1sc.add_subplot fig1sc.set_size_inches(figsize) ax1sc.set_title("Simple pendulum animation, L=" + str(L) + "m", fontsize="medium") ax1sc.set_xlabel("Time (s)", color='dimgray', fontsize=fontsize) ax1sc.set_ylabel("Amplitudes", color='dimgray', fontsize=fontsize) ax1sc.tick_params(labelsize=fontsize)

# pandas_alive scatter_chart = df.plot_animated(filename="pend-scatter.gif", kind='scatter', period_label={'x': 0.05, 'y': 0.9}, steps_per_period=1, interpolate_period=False, period_length=50, period_fmt='Time:{x:10.2f}', enable_progress_bar=True, fixed_max=True, dpi=100, fig=fig1sc, size="ang_vel" ) plt.close

print("Points size follows one of the pd columns: ang_vel")# Video('./pend-scatter.gif', html_attributes="controls muted autoplay")

# set up and generate animated bar race chart## set up figure to pass onto `pandas_alive`# NOTE: by using Figure (capital F) instead of figure `FuncAnimation` seems to run twice as fast! fig2 = plt.Figure ax2 = fig2.add_subplot fig2.set_size_inches(figsize) ax2.set_title("Simple pendulum animation, L=" + str(L) + "m", fontsize="medium") ax2.set_xlabel("Amplitudes", color='dimgray', fontsize=fontsize) ax2.set_ylabel("", color='dimgray', fontsize="x-small") ax2.tick_params(labelsize=fontsize)

# pandas_alive race_chart = df.plot_animated(filename="pend-race.gif", kind='race', period_label={'x': 0.05, 'y': 0.9}, steps_per_period=1, interpolate_period=False, period_length=50, period_fmt='Time:{x:10.2f}', enable_progress_bar=True, fixed_max=False, dpi=100, fig=fig2 ) plt.close

# set up and generate bubble animated plot#

# set up figure to pass onto `pandas_alive`# NOTE: by using Figure (capital F) instead of figure `FuncAnimation` seems to run twice as fast! fig3 = plt.Figure ax3 = fig3.add_subplot fig3.set_size_inches(figsize) ax3.set_title("Simple pendulum animation, L=" + str(L) + "m", fontsize="medium") ax3.set_xlabel("Hor Displacement (m)", color='dimgray', fontsize=fontsize) ax3.set_ylabel("Ver Displacement (m)", color='dimgray', fontsize=fontsize)# limits & ratio below get the graph square ax3.set_xlim(-L * ax_scale, L * ax_scale) ax3.set_ylim(-L * ax_scale - 0.1, L * ax_scale - 0.1) ratio = 1. # this is visual ratio of axes ax3.set_aspect(ratio / ax3.get_data_ratio)

ax3.arrow(0, 0, df2["dx (m)"].iloc[-1], df2["dy (m)"].iloc[-1], color="dimgray", ls=":", lw=1, width=.0, head_width=0, zorder=-1)

# pandas_alive bubble_chart = df2.plot_animated( kind="bubble", filename="pend-bubble.gif", x_data_label="dx (m)", y_data_label="dy (m)", size_data_label="size", color_data_label="ang_vel", cmap="jet", period_label={'x': 0.05, 'y': 0.9}, vmin=None, vmax=None, steps_per_period=1, interpolate_period=False, period_length=50, period_fmt='Time:{x:10.2f}s', enable_progress_bar=True, fixed_max=False, dpi=dpi, fig=fig3 ) plt.close

print("Bubble size & colour animates with pd data column for ang_vel.")

# Combined plots# fontsize = "x-small"# Otherwise titles overlap and subplots_adjust does nothingfrom matplotlib import rcParams rcParams.update({"figure.autolayout": False})

figs = plt.Figure(figsize=(9, 4), dpi=100) figs.subplots_adjust(wspace=0.1) gs = figs.add_gridspec(2, 2)

ax1 = figs.add_subplot(gs[0, 0]) ax1.set_xlabel("Time(s)", color='dimgray', fontsize=fontsize) ax1.set_ylabel("Amplitudes", color='dimgray', fontsize=fontsize) ax1.tick_params(labelsize=fontsize)

ax2 = figs.add_subplot(gs[1, 0]) ax2.set_xlabel("Amplitudes", color='dimgray', fontsize=fontsize) ax2.set_ylabel("", color='dimgray', fontsize=fontsize) ax2.tick_params(labelsize=fontsize)

ax3 = figs.add_subplot(gs[:, 1]) ax3.set_xlabel("Hor Displacement (m)", color='dimgray', fontsize=fontsize) ax3.set_ylabel("Ver Displacement (m)", color='dimgray', fontsize=fontsize) ax3.tick_params(labelsize=fontsize)# limits & ratio below get the graph square ax3.set_xlim(-L * ax_scale, L * ax_scale) ax3.set_ylim(-L * ax_scale - 0.1, L * ax_scale - 0.1) ratio = 1. # this is visual ratio of axes ax3.set_aspect(ratio / ax3.get_data_ratio)

line_chart.ax = ax1 race_chart.ax = ax2 bubble_chart.ax = ax3

plots = [line_chart, race_chart, bubble_chart]# pandas_alive combined using custom figure pandas_alive.animate_multiple_plots( filename='pend-combined.gif', plots=plots, custom_fig=figs, dpi=100, enable_progress_bar=True, adjust_subplot_left=0.2, adjust_subplot_right=None, title="Simple pendulum animations, L=" + str(L) + "m", title_fontsize="medium" ) plt.close

最後如果你想完成中文動態圖表的製作,加入中文顯示代碼即可。

# 中文顯示plt.rcParams['font.sans-serif'] = ['SimHei'] # Windowsplt.rcParams['font.sans-serif'] = ['Hiragino Sans GB'] # Macplt.rcParams['axes.unicode_minus'] = False

# 讀取數據df_result = pd.read_csv('data/yuhuanshui.csv', index_col=0, parse_dates=[0])# 生成圖表animated_line_chart = df_result.diff.fillna(0).plot_animated(kind='line', period_label=False, add_legend=False)animated_bar_chart = df_result.plot_animated(n_visible=10)pandas_alive.animate_multiple_plots('examples/yuhuanshui.gif', [animated_bar_chart, animated_line_chart], enable_progress_bar=True, title='我是餘歡水演職人員熱度排行')

還是使用演員的百度指數數據。

GitHub地址:

https://github.com/JackMcKew/pandas_alive

使用文檔:

https://jackmckew.github.io/pandas_alive/

相關焦點

  • Python趣味打怪:60秒學會一個例子,147段代碼助你從入門到大師
    入門簡單如十進位轉二進位,盡顯Python簡潔之美:In [1]: bin(10)Out[1]: '0b1010'冬天到了,就算沒有點亮手繪技能,也能用簡單幾行代碼繪出漫天雪花:>例子是有趣的例子,教程也是正經教程,學習路徑清晰、系統,先一起來看看完整目錄:學習路徑施工完成:1、Python基礎2、Python字符串和正則化3、Python文件4、Python日期5、Python利器6、Python畫圖7、Python實戰施工中:Python基礎算法
  • Python趣味打怪:147段簡單代碼完成從入門到大師
    入門簡單如十進位轉二進位,盡顯Python簡潔之美:In [1]: bin(10)Out[1]: '0b1010'冬天到了,就算沒有點亮手繪技能,也能用簡單幾行代碼繪出漫天雪花:例子是有趣的例子,教程也是正經教程,學習路徑清晰、系統,先一起來看看完整目錄:
  • Python圖表繪製進擊,一文學會如何調整刻度範圍和刻度標籤
    首先咱們來聊一下第9行和第15行所調用的subplot()函數,這個函數是一個子區間函數,也就是說通過設置該函數可將圖表顯示在特定的位置,subplot()函數是專門用來繪製集合形狀相同的網格區域,也就是將咱們所繪製圖表的畫布分成若干個子畫布,這些子畫布就構成了矩形繪圖區域,然後在這些繪圖區域上分別進行圖形繪製,比如第9行的subplot(211)和第15行的subplot(212)是指首先在畫布上分隔出一個
  • 漂亮圖表也可信手拈來,一文學會用Python繪製堆積折線圖
    其實這個堆積折線圖在咱們日常生活中最為常見哦,比如常見的股市走勢圖就是典型的堆積折線圖哦,說一下它的官方定義吧,堆積折線圖就是通過繪製不同數據集的折線圖生成的圖表,是按照垂直方向上彼此堆疊且又不相互覆蓋的排列順序,繪製若干條折線圖形成的組合圖形哦!
  • Python數據可視化實例之繪製圖表
    Python數據可視化實例之繪製圖表原創 蟲蟲安全 2018-09-05 17:41:57得利於語言的簡單明了、豐富的數據結構、豐富的類和模塊,Python如今成了數據科學中的香餑餑,成了matlab、R語言之外又一強大的數據分析工具。拋開其他方面的、今天蟲蟲帶大家一起來探索Python在數據可視化方面的應用。
  • 基本初等函數 指數函數 代碼篇
    上一篇文章中,我們為大家介紹了基本初等函數中的指數函數 基本初等函數 指數函數,本文將為大家介紹如何利用python語言完成函數的繪製。本文將要繪製指數函數y=2^x準備數據自變量x我們可以利用numpy提供的linspace函數,均勻的生成-10到10之間的10000個數,然後再計算y的值,相關代碼如下:import numpy as npx = np.linspace(-
  • 程式設計師的樂趣,生成自定義二維碼,5行Python代碼就搞定
    生成二維碼的工具也層出不窮,但多數需要在線完成,並且生成的圖案也千篇一律,過於單調。那麼有沒有辦法實現自定義生成二維碼呢?近日,一位熱衷於終身學習的工程師兼攝影師 Arindom Bhattacharjee 撰寫了一篇自定義生成二維碼的方法,並且整個生成過程只需要 5 行 Python 代碼即可完成。感興趣的讀者可以自己實現下。
  • 「python opencv計算機視覺零基礎到實戰」九模糊
    一、學習目標了解什麼是卷積了解模糊的使用方法與應用目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python opencv視覺入門到實戰」 第四節色彩空間
  • 如何構建一個基於可視化理論的完美Python圖表?
    根據我(以及Edward Tufte)的經驗,卓越的圖表源於許多小變化累積出的優勢。對圖形的每一處著墨都是至關重要的。本教程只有所需的少數幾行代碼,以便簡潔真實地展示數據。對於所有的數據科學家和信息學迷,《定量信息的視覺展示》絕對是一本咖啡桌書籍。在展示信息方面這本書是無可爭議的王,而且趣味性十足。
  • 超硬核的 Python 數據可視化教程!
    Seaborn是一個基於matplotlib的高級可視化效果庫,針對的點主要是數據挖掘和機器學習中的變量特徵選取,seaborn可以用短小的代碼去繪製描述更多維度數據的可視化效果圖其他庫還包括Bokeh(是一個用於做瀏覽器端交互可視化的庫,實現分析師與數據的交互);Mapbox(處理地理數據引擎更強的可視化工具庫)等等本篇文章主要使用
  • 1行代碼實現Python數據分析:圖表美觀清晰,自帶對比功能丨開源
    現在,GitHub上一位博主告訴你:不用學,用sweetviz就行。這是一個基於Python編寫的數據分析軟體,只要掌握3種函數用法,一行Python代碼就能實現數據集可視化、分析與比較。我們以Titanic數據集為例,輸入一行代碼:一個1080p的清晰網頁界面就出現在了眼前。
  • Python學習第90課-數據可視化之散點圖繪製
    【每天幾分鐘,從零入門python編程的世界!】今天我們學習散點圖,在統計學或者機器學習方面,或者在金融風險控制方面,金融風險控制經常要看異常交易、信貸風險,做這樣的分析就要用到一個圖--散點圖(scatter plot)。
  • 韋編|五分鐘學會Seaborn常用圖表繪製
    下面選取常用的幾種圖表繪圖示例,並給出函數的參數注釋,大多圖表都可以通過一行代碼實現繪圖功能,五分鐘的時間即可掌握常用圖表的繪製。本文使用Jupyter Notebook編寫代碼,首先導入繪圖模塊:import seaborn as sns import matplotlib.pyplot as plt %matplotlib inlineNo.1lmplotlmplot主要用於可視化線性回歸關係,可以觀察兩組數據之間是否存在線性關係。
  • 數據分析從業者必看,10 個加速 python 數據分析的簡單的小技巧
    還可以將報告導出到具有以下代碼的交互式 HTML 文件中。相反,也不能排除使用 pandas.dataframe.plot()函數繪製圖表的易用性。如果我們不需要對代碼進行重大修改,就可以像繪製 pandas plots 那樣繪出交互式圖表呢?你可以在 Cufflinks 庫的幫助下做到這一點。Cufflinks 將 plotly 的力量與 pandas 的靈活性結合起來,便於繪製。
  • Python圖表繪製繼續進階,一文學會做自己獨特和帥氣的圖例
    首先,咱們一起聊聊Python所生成的圖表中關於圖例的樣式的內容上次咱們在調用legend()函數時,對其內部的關鍵字參數loc進行了設置,通過對loc參數的設置可以將圖例顯示在圖表的不同位置,其實對於圖例的樣式也是可以進行設置和調整的,對於圖例的樣式,我們可以設置圖例的外邊框、文本標籤的排列位置以及其相應的投影效果等。
  • 數據科學的Python軟體包
    Python使用簡單明了的語法來編寫代碼,用Python編寫代碼非常容易,感覺就像您是用英語編寫直接指令一樣。減少編碼數據科學和機器算法非常複雜,因此我們需要一種可以輕鬆實現並減少代碼數量的程式語言。Python帶有平滑且縮進的語法,可幫助開發人員在更少的代碼中構建程序。圖書館開源庫和第三方庫是Python的主要資產。
  • Python教程|用代碼打開聖誕節的奇妙姿勢!
    早年的電腦發展遠不如現在發達,隨意播放高清視頻,發送動態表情包在當時來說是非常困難的。於是就有了這個:使用電腦字符(主要是ASCII)來表達圖形或者圖像。當然,還有一批「著名」的表情,讓我們來看看你能不能辨認出這些表情?
  • 從零開始學Python,帶你手把手實戰之一
    大家好,最近有些小夥伴在後臺給我留言說想要一些Python的實戰項目,能夠動手寫下代碼來實戰練習一下Python。我整理了一下我之前搜集的一些資料以及我個人的一些理解,給大家開設了這個專題。要完成這個課題呢,需要了解Python基礎的輸入輸出以及循環的寫法,也需要了解二分法。最後完成的效果大概是這樣的:
  • 論文繪圖神器:一行代碼繪製不同期刊格式圖表,哈佛博士後開源
    賈浩楠 發自 凹非寺量子位 報導 | 公眾號 QbitAI「一篇論文投多個期刊,每個期刊對圖表格式要求不一,同一組數據要用多種工具分別繪圖。」不光是你,哈佛大學天文研究所的博士後,也不堪忍受論文重複繪圖之苦。
  • 基於Python的圖表繪圖系統matplotlib,「動態條形圖」你了解嗎?
    雖然我沒有對國力提升做出什麼不可磨滅的貢獻,但是我可以探索下動態條形圖是怎樣繪製的,應該也算是傳播知識了吧(笑哭)。選取每年前十的球隊進入數據集,最終的數據集長這個樣子:我們一步一步來,先繪製一個簡單的條形圖,比如繪製2019年排名前十球隊積分的條形圖,準備數據,把2019年的數據提取出來然後進行排序並選擇前十名的球隊數據,具體代碼如下:year = 2019dff = (df_t[df_t["年份"].eq(year)] .sort_values(by='積分