家好,我是小F~
數據可視化是數據科學中關鍵的一步。
在以圖形方式表現某些數據時,Python能夠提供很大的幫助。
不過有些小伙伴也會遇到不少問題,比如選擇何種圖表,以及如何制作,代碼如何編寫,這些都是問題!
今天給大家介紹一個Python圖表大全,40個種類,總計約400個示例圖表。
分為7個大系列,分布、關系、排行、局部整體、時間序列、地理空間、流程。
文檔地址
https://www.python-graph-gallery.com
GitHub地址
https://github.com/holtzy/The-Python-Graph-Gallery
給大家提供了示例及代碼,幾分鐘內就能構建一個你所需要的圖表。
下面就給大家介紹一下~
01. 小提琴圖
小提琴圖可以將一組或多組數據的數值變量分布可視化。
相比有時會隱藏數據特征的箱形圖相比,小提琴圖值得更多關注。
import seaborn as sns
import matplotlib.pyplot as plt# 加載數據
df = sns.load_dataset('iris', data_home='seaborn-data', cache=True)# 繪圖顯示
sns.violinplot(x=df["species"], y=df["sepal_length"])
plt.show()
使用Seaborn的violinplot()進行繪制,結果如下。
02. 核密度估計圖
核密度估計圖其實是對直方圖的一個自然拓展。
可以可視化一個或多個組的數值變量的分布,非常適合大型數據集。
import seaborn as sns
import matplotlib.pyplot as plt# 加載數據
df = sns.load_dataset('iris', data_home='seaborn-data', cache=True)# 繪圖顯示
sns.kdeplot(df['sepal_width'])
plt.show()
使用Seaborn的kdeplot()進行繪制,結果如下。
03. 直方圖
直方圖,可視化一組或多組數據的分布情況。
import seaborn as sns
import matplotlib.pyplot as plt# 加載數據
df = sns.load_dataset('iris', data_home='seaborn-data', cache=True)# 繪圖顯示
sns.distplot(a=df["sepal_length"], hist=True, kde=False, rug=False)
plt.show()
使用Seaborn的distplot()進行繪制,結果如下。
04. 箱形圖
箱形圖,可視化一組或多組數據的分布情況。
可以快速獲得中位數、四分位數和異常值,但也隱藏數據集的各個數據點。
import seaborn as sns
import matplotlib.pyplot as plt# 加載數據
df = sns.load_dataset('iris', data_home='seaborn-data', cache=True)# 繪圖顯示
sns.boxplot(x=df["species"], y=df["sepal_length"])
plt.show()
使用Seaborn的boxplot()進行繪制,結果如下。
05. 山脊線圖
山脊線圖,總結幾組數據的分布情況。
每個組都表示為一個密度圖,每個密度圖相互重疊以更有效地利用空間。
import plotly.graph_objects as go
import numpy as np
import pandas as pd# 讀取數據
temp = pd.read_csv('2016-weather-data-seattle.csv')
# 數據處理, 時間格式轉換
temp['year'] = pd.to_datetime(temp['Date']).dt.year# 選擇幾年的數據展示即可
year_list = [1950, 1960, 1970, 1980, 1990, 2000, 2010]
temp = temp[temp['year'].isin(year_list)]# 繪制每年的直方圖,以年和平均溫度分組,并使用'count'函數進行匯總
temp = temp.groupby(['year', 'Mean_TemperatureC']).agg({'Mean_TemperatureC': 'count'}).rename(columns={'Mean_TemperatureC': 'count'}).reset_index()# 使用Plotly繪制脊線圖,每個軌跡對應于特定年份的溫度分布
# 將每年的數據(溫度和它們各自的計數)存儲在單獨的數組,并將其存儲在字典中以方便檢索
array_dict = {}
for year in year_list:
# 每年平均溫度
array_dict[f'x_{year}'] = temp[temp['year'] == year]['Mean_TemperatureC']
# 每年溫度計數
array_dict[f'y_{year}'] = temp[temp['year'] == year]['count']
array_dict[f'y_{year}'] = (array_dict[f'y_{year}'] - array_dict[f'y_{year}'].min()) \
/ (array_dict[f'y_{year}'].max() - array_dict[f'y_{year}'].min())# 創建一個圖像對象
fig = go.Figure()
for index, year in enumerate(year_list):
# 使用add_trace()繪制軌跡
fig.add_trace(go.Scatter(
x=[-20, 40], y=np.full(2, len(year_list) - index),
mode='lines',
line_color='white')) fig.add_trace(go.Scatter(
x=array_dict[f'x_{year}'],
y=array_dict[f'y_{year}'] + (len(year_list) - index) + 0.4,
fill='tonexty',
name=f'{year}')) # 添加文本
fig.add_annotation(
x=-20,
y=len(year_list) - index,
text=f'{year}',
showarrow=False,
yshift=10)# 添加標題、圖例、xy軸參數
fig.update_layout(
title='1950年~2010年西雅圖平均溫度',
showlegend=False,
xaxis=dict(title='單位: 攝氏度'),
yaxis=dict(showticklabels=False)
)# 跳轉網頁顯示
fig.show()
Seaborn沒有專門的函數來繪制山脊線圖,可以多次調用kdeplot()來制作。
結果如下。
06. 散點圖
散點圖,顯示2個數值變量之間的關系。
import seaborn as sns
import matplotlib.pyplot as plt# 加載數據
df = sns.load_dataset('iris', data_home='seaborn-data', cache=True)# 繪圖顯示
sns.regplot(x=df["sepal_length"], y=df["sepal_width"])
plt.show()
使用Seaborn的regplot()進行繪制,結果如下。
07. 矩形熱力圖
矩形熱力圖,矩陣中的每個值都被表示為一個顏色數據。
import seaborn as sns
import pandas as pd
import numpy as np# Create a dataset
df = pd.DataFrame(np.random.random((5,5)), columns=["a","b","c","d","e"])# Default heatmap
p1 = sns.heatmap(df)
使用Seaborn的heatmap()進行繪制,結果如下。
08. 相關性圖
相關性圖或相關矩陣圖,分析每對數據變量之間的關系。
相關性可視化為散點圖,對角線用直方圖或密度圖表示每個變量的分布。
import seaborn as sns
import matplotlib.pyplot as plt# 加載數據
df = sns.load_dataset('iris', data_home='seaborn-data', cache=True)# 繪圖顯示
sns.pairplot(df)
plt.show()
使用Seaborn的pairplot()進行繪制,結果如下。
09. 氣泡圖
氣泡圖其實就是一個散點圖,其中圓圈大小被映射到第三數值變量的值。
import matplotlib.pyplot as plt
import seaborn as sns
from gapminder import gapminder# 導入數據
data = gapminder.loc[gapminder.year == 2007]# 使用scatterplot創建氣泡圖
sns.scatterplot(data=data, x="gdpPercap", y="lifeExp", size="pop", legend=False, sizes=(20, 2000))# 顯示
plt.show()
使用Seaborn的scatterplot()進行繪制,結果如下。
10. 連接散點圖
連接散點圖就是一個線圖,其中每個數據點由圓形或任何類型的標記展示。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd# 創建數據
df = pd.DataFrame({'x_axis': range(1, 10), 'y_axis': np.random.randn(9) * 80 + range(1, 10)})# 繪制顯示
plt.plot('x_axis', 'y_axis', data=df, linestyle='-', marker='o')
plt.show()
使用Matplotlib的plot()進行繪制,結果如下。
11. 二維密度圖
二維密度圖或二維直方圖,可視化兩個定量變量的組合分布。
它們總是在X軸上表示一個變量,另一個在Y軸上,就像散點圖。
然后計算二維空間特定區域內的次數,并用顏色漸變表示。
形狀變化:六邊形a hexbin chart,正方形a 2d histogram,核密度2d density plots或contour plots。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde# 創建數據, 200個點
data = np.random.multivariate_normal([0, 0], [[1, 0.5], [0.5, 3]], 200)
x, y = data.T# 創建畫布, 6個子圖
fig, axes = plt.subplots(ncols=6, nrows=1, figsize=(21, 5))# 第一個子圖, 散點圖
axes[0].set_title('Scatterplot')
axes[0].plot(x, y, 'ko')# 第二個子圖, 六邊形
nbins = 20
axes[1].set_title('Hexbin')
axes[1].hexbin(x, y, gridsize=nbins, cmap=plt.cm.BuGn_r)# 2D 直方圖
axes[2].set_title('2D Histogram')
axes[2].hist2d(x, y, bins=nbins, cmap=plt.cm.BuGn_r)# 高斯kde
k = kde.gaussian_kde(data.T)
xi, yi = np.mgrid[x.min():x.max():nbins * 1j, y.min():y.max():nbins * 1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))# 密度圖
axes[3].set_title('Calculate Gaussian KDE')
axes[3].pcolormesh(xi, yi, zi.reshape(xi.shape), shading='auto', cmap=plt.cm.BuGn_r)# 添加陰影
axes[4].set_title('2D Density with shading')
axes[4].pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud', cmap=plt.cm.BuGn_r)# 添加輪廓
axes[5].set_title('Contour')
axes[5].pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud', cmap=plt.cm.BuGn_r)
axes[5].contour(xi, yi, zi.reshape(xi.shape))plt.show()
使用Matplotlib和scipy進行繪制,結果如下。
12. 條形圖
條形圖表示多個明確的變量的數值關系。每個變量都為一個條形。條形的大小代表其數值。
import numpy as np
import matplotlib.pyplot as plt# 生成隨機數據
height = [3, 12, 5, 18, 45]
bars = ('A', 'B', 'C', 'D', 'E')
y_pos = np.arange(len(bars))# 創建條形圖
plt.bar(y_pos, height)# x軸標簽
plt.xticks(y_pos, bars)# 顯示
plt.show()
使用Matplotlib的bar()進行繪制,結果如下。
13. 雷達圖
雷達圖,可以可視化多個定量變量的一個或多個系列的值。
每個變量都有自己的軸,所有軸都連接在圖形的中心。
import matplotlib.pyplot as plt
import pandas as pd
from math import pi# 設置數據
df = pd.DataFrame({
'group': ['A', 'B', 'C', 'D'],
'var1': [38, 1.5, 30, 4],
'var2': [29, 10, 9, 34],
'var3': [8, 39, 23, 24],
'var4': [7, 31, 33, 14],
'var5': [28, 15, 32, 14]
})# 目標數量
categories = list(df)[1:]
N = len(categories)# 角度
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]# 初始化
ax = plt.subplot(111, polar=True)# 設置第一處
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)# 添加背景信息
plt.xticks(angles[:-1], categories)
ax.set_rlabel_position(0)
plt.yticks([10, 20, 30], ["10", "20", "30"], color="grey", size=7)
plt.ylim(0, 40)# 添加數據圖# 第一個
values = df.loc[0].drop('group').values.flatten().tolist()
values += values[:1]
ax.plot(angles, values, linewidth=1, linestyle='solid', label="group A")
ax.fill(angles, values, 'b', alpha=0.1)# 第二個
values = df.loc[1].drop('group').values.flatten().tolist()
values += values[:1]
ax.plot(angles, values, linewidth=1, linestyle='solid', label="group B")
ax.fill(angles, values, 'r', alpha=0.1)# 添加圖例
plt.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))# 顯示
plt.show()
使用Matplotlib進行繪制,結果如下。
14. 詞云圖
詞云圖是文本數據的視覺表示。
單詞通常是單個的,每個單詞的重要性以字體大小或顏色表示。
from wordcloud import WordCloud
import matplotlib.pyplot as plt# 添加詞語
text=("Python Python Python Matplotlib Chart Wordcloud Boxplot")# 創建詞云對象
wordcloud = WordCloud(width=480, height=480, margin=0).generate(text)# 顯示詞云圖
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.margins(x=0, y=0)
plt.show()
使用wordcloud進行繪制,結果如下。
15. 平行座標圖
一個平行座標圖,能夠比較不同系列相同屬性的數值情況。
Pandas可能是繪制平行坐標圖的最佳方式。
import seaborn as sns
import matplotlib.pyplot as plt
from pandas.plotting import parallel_coordinates# 讀取數據
data = sns.load_dataset('iris', data_home='seaborn-data', cache=True)# 創建圖表
parallel_coordinates(data, 'species', colormap=plt.get_cmap("Set2"))# 顯示
plt.show()
使用Pandas的parallel_coordinates()進行繪制,結果如下。
16. 棒棒糖圖
棒棒糖圖其實就是柱狀圖的變形,顯示一個線段和一個圓。
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np# 創建數據
df = pd.DataFrame({'group': list(map(chr, range(65, 85))), 'values': np.random.uniform(size=20) })# 排序取值
ordered_df = df.sort_values(by='values')
my_range = range(1, len(df.index)+1)# 創建圖表
plt.stem(ordered_df['values'])
plt.xticks(my_range, ordered_df['group'])# 顯示
plt.show()
使用Matplotlib的stem()進行繪制,結果如下。
17. 徑向柱圖
徑向柱圖同樣也是條形圖的變形,但是使用極坐標而不是直角坐標系。
繪制起來有點麻煩,而且比柱狀圖準確度低,但更引人注目。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np# 生成數據
df = pd.DataFrame(
{
'Name': ['item ' + str(i) for i in list(range(1, 51)) ],
'Value': np.random.randint(low=10, high=100, size=50)
})# 排序
df = df.sort_values(by=['Value'])# 初始化畫布
plt.figure(figsize=(20, 10))
ax = plt.subplot(111, polar=True)
plt.axis('off')# 設置圖表參數
upperLimit = 100
lowerLimit = 30
labelPadding = 4# 計算最大值
max = df['Value'].max()# 數據下限10, 上限100
slope = (max - lowerLimit) / max
heights = slope * df.Value + lowerLimit# 計算條形圖的寬度
width = 2*np.pi / len(df.index)# 計算角度
indexes = list(range(1, len(df.index)+1))
angles = [element * width for element in indexes]# 繪制條形圖
bars = ax.bar(
x=angles,
height=heights,
width=width,
bottom=lowerLimit,
linewidth=2,
edgecolor="white",
color="#61a4b2",
)# 添加標簽
for bar, angle, height, label in zip(bars,angles, heights, df["Name"]): # 旋轉
rotation = np.rad2deg(angle) # 翻轉
alignment = ""
if angle >= np.pi/2 and angle < 3*np.pi/2:
alignment = "right"
rotation = rotation + 180
else:
alignment = "left" # 最后添加標簽
ax.text(
x=angle,
y=lowerLimit + bar.get_height() + labelPadding,
s=label,
ha=alignment,
va='center',
rotation=rotation,
rotation_mode="anchor")plt.show()
使用Matplotlib進行繪制,結果如下。
18. 矩形樹圖
矩形樹圖是一種常見的表達『層級數據』『樹狀數據』的可視化形式。
它主要用面積的方式,便于突出展現出『樹』的各層級中重要的節點。
import matplotlib.pyplot as plt
import squarify
import pandas as pd# 創建數據
df = pd.DataFrame({'nb_people': [8, 3, 4, 2], 'group': ["group A", "group B", "group C", "group D"]})# 繪圖顯示
squarify.plot(sizes=df['nb_people'], label=df['group'], alpha=.8 )
plt.axis('off')
plt.show()
使用squarify庫進行繪制,結果如下。
19. 維恩圖
維恩圖,顯示不同組之間所有可能的關系。
import matplotlib.pyplot as plt
from matplotlib_venn import venn2# 創建圖表
venn2(subsets=(10, 5, 2), set_labels=('Group A', 'Group B'))# 顯示
plt.show()
使用matplotlib_venn庫進行繪制,結果如下。
20. 圓環圖
圓環圖,本質上就是一個餅圖,中間切掉了一個區域。
import matplotlib.pyplot as plt# 創建數據
size_of_groups = [12, 11, 3, 30]# 生成餅圖
plt.pie(size_of_groups)# 在中心添加一個圓, 生成環形圖
my_circle = plt.Circle((0, 0), 0.7, color='white')
p = plt.gcf()
p.gca().add_artist(my_circle)plt.show()
使用Matplotlib進行繪制,結果如下。
21. 餅圖
餅圖,最常見的可視化圖表之一。
將圓劃分成一個個扇形區域,每個區域代表在整體中所占的比例。
import matplotlib.pyplot as plt# 創建數據
size_of_groups = [12, 11, 3, 30]# 生成餅圖
plt.pie(size_of_groups)
plt.show()
使用Matplotlib進行繪制,結果如下。
22. 樹圖
樹圖主要用來可視化樹形數據結構,是一種特殊的層次類型,具有唯一的根節點,左子樹,和右子樹。
import pandas as pd
from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage# 讀取數據
df = pd.read_csv('mtcars.csv')
df = df.set_index('model')# 計算每個樣本之間的距離
Z = linkage(df, 'ward')# 繪圖
dendrogram(Z, leaf_rotation=90, leaf_font_size=8, labels=df.index)# 顯示
plt.show()
使用Scipy進行繪制,結果如下。
23. 氣泡圖
氣泡圖,表示層次結構及數值大小。
import circlify
import matplotlib.pyplot as plt# 創建畫布, 包含一個子圖
fig, ax = plt.subplots(figsize=(14, 14))# 標題
ax.set_title('Repartition of the world population')# 移除坐標軸
ax.axis('off')# 人口數據
data = [{'id': 'World', 'datum': 6964195249, 'children': [
{'id': "North America", 'datum': 450448697,
'children': [
{'id': "United States", 'datum': 308865000},
{'id': "Mexico", 'datum': 107550697},
{'id': "Canada", 'datum': 34033000}
]},
{'id': "South America", 'datum': 278095425,
'children': [
{'id': "Brazil", 'datum': 192612000},
{'id': "Colombia", 'datum': 45349000},
{'id': "Argentina", 'datum': 40134425}
]},
{'id': "Europe", 'datum': 209246682,
'children': [
{'id': "Germany", 'datum': 81757600},
{'id': "France", 'datum': 65447374},
{'id': "United Kingdom", 'datum': 62041708}
]},
{'id': "Africa", 'datum': 311929000,
'children': [
{'id': "Nigeria", 'datum': 154729000},
{'id': "Ethiopia", 'datum': 79221000},
{'id': "Egypt", 'datum': 77979000}
]},
{'id': "Asia", 'datum': 2745929500,
'children': [
{'id': "China", 'datum': 1336335000},
{'id': "India", 'datum': 1178225000},
{'id': "Indonesia", 'datum': 231369500}
]}
]}]# 使用circlify()計算, 獲取圓的大小, 位置
circles = circlify.circlify(
data,
show_enclosure=False,
target_enclosure=circlify.Circle(x=0, y=0, r=1)
)lim = max(
max(
abs(circle.x) + circle.r,
abs(circle.y) + circle.r,
)
for circle in circles
)
plt.xlim(-lim, lim)
plt.ylim(-lim, lim)for circle in circles:
if circle.level != 2:
continue
x, y, r = circle
ax.add_patch(plt.Circle((x, y), r, alpha=0.5, linewidth=2, color="lightblue"))for circle in circles:
if circle.level != 3:
continue
x, y, r = circle
label = circle.ex["id"]
ax.add_patch(plt.Circle((x, y), r, alpha=0.5, linewidth=2, color="#69b3a2"))
plt.annotate(label, (x, y), ha='center', color="white")for circle in circles:
if circle.level != 2:
continue
x, y, r = circle
label = circle.ex["id"]
plt.annotate(label, (x, y), va='center', ha='center', bbox=dict(facecolor='white', edgecolor='black', boxstyle='round', pad=.5))plt.show()
使用Circlify進行繪制,結果如下。
24. 折線圖
折線圖是最常見的圖表類型之一。
將各個數據點標志連接起來的圖表,用于展現數據的變化趨勢。
import matplotlib.pyplot as plt
import numpy as np# 創建數據
values = np.cumsum(np.random.randn(1000, 1))# 繪制圖表
plt.plot(values)
plt.show()
使用Matplotlib進行繪制,結果如下。
25. 面積圖
面積圖和折線圖非常相似,區別在于和x坐標軸間是否被顏色填充。
import matplotlib.pyplot as plt# 創建數據
x = range(1, 6)
y = [1, 4, 6, 8, 4]# 生成圖表
plt.fill_between(x, y)
plt.show()
使用Matplotlib的fill_between()進行繪制,結果如下。
26. 堆疊面積圖
堆疊面積圖表示若干個數值變量的數值演變。
每個顯示在彼此的頂部,易于讀取總數,但較難準確讀取每個的值。
import matplotlib.pyplot as plt# 創建數據
x = range(1, 6)
y1 = [1, 4, 6, 8, 9]
y2 = [2, 2, 7, 10, 12]
y3 = [2, 8, 5, 10, 6]# 生成圖表
plt.stackplot(x, y1, y2, y3, labels=['A', 'B', 'C'])
plt.legend(loc='upper left')
plt.show()
使用Matplotlib的stackplot()進行繪制,結果如下。
27. 河流圖
河流圖是一種特殊的流圖, 它主要用來表示事件或主題等在一段時間內的變化。
圍繞著中心軸顯示,且邊緣是圓形的,從而形成流動的形狀。
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats# 添加數據
x = np.arange(1990, 2020)
y = [np.random.randint(0, 5, size=30) for _ in range(5)]def gaussian_smooth(x, y, grid, sd):
"""平滑曲線"""
weights = np.transpose([stats.norm.pdf(grid, m, sd) for m in x])
weights = weights / weights.sum(0)
return (weights * y).sum(1)# 自定義顏色
COLORS = ["#D0D1E6", "#A6BDDB", "#74A9CF", "#2B8CBE", "#045A8D"]# 創建畫布
fig, ax = plt.subplots(figsize=(10, 7))# 生成圖表
grid = np.linspace(1985, 2025, num=500)
y_smoothed = [gaussian_smooth(x, y_, grid, 1) for y_ in y]
ax.stackplot(grid, y_smoothed, colors=COLORS, baseline="sym")# 顯示
plt.show()
先使用Matplotlib繪制堆積圖,設置stackplot()的baseline參數,可將數據圍繞x軸展示。
再通過scipy.interpolate平滑曲線,最終結果如下。
28. 時間序列圖
時間序列圖是指能夠展示數值演變的所有圖表。
比如折線圖、柱狀圖、面積圖等等。
import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt# 創建數據
my_count = ["France", "Australia", "Japan", "USA", "Germany", "Congo", "China", "England", "Spain", "Greece", "Marocco",
"South Africa", "Indonesia", "Peru", "Chili", "Brazil"]
df = pd.DataFrame({
"country": np.repeat(my_count, 10),
"years": list(range(2000, 2010)) * 16,
"value": np.random.rand(160)
})# 創建網格
g = sns.FacetGrid(df, col='country', hue='country', col_wrap=4, )# 添加曲線圖
g = g.map(plt.plot, 'years', 'value')# 面積圖
g = g.map(plt.fill_between, 'years', 'value', alpha=0.2).set_titles("{col_name} country")# 標題
g = g.set_titles("{col_name}")# 總標題
plt.subplots_adjust(top=0.92)
g = g.fig.suptitle('Evolution of the value of stuff in 16 countries')# 顯示
plt.show()
下面以一個時間序列面積圖為例,顯示多組數據,結果如下。
29. 地圖
所有的地理空間數據分析應該都離不開地圖吧!
import pandas as pd
import folium# 創建地圖對象
m = folium.Map(location=[20, 0], tiles="OpenStreetMap", zoom_start=2)# 創建圖標數據
data = pd.DataFrame({
'lon': [-58, 2, 145, 30.32, -4.03, -73.57, 36.82, -38.5],
'lat': [-34, 49, -38, 59.93, 5.33, 45.52, -1.29, -12.97],
'name': ['Buenos Aires', 'Paris', 'melbourne', 'St Petersbourg', 'Abidjan', 'Montreal', 'Nairobi', 'Salvador'],
'value': [10, 12, 40, 70, 23, 43, 100, 43]
}, dtype=str)# 添加信息
for i in range(0,len(data)):
folium.Marker(
location=[data.iloc[i]['lat'], data.iloc[i]['lon']],
popup=data.iloc[i]['name'],
).add_to(m)# 保存
m.save('map.html')
使用Folium繪制谷歌地圖風格的地圖,結果如下。
30. 等值域地圖
等值域地圖,相同數值范圍,著色相同。
import pandas as pd
import folium# 創建地圖對象
m = folium.Map(location=[40, -95], zoom_start=4)# 讀取數據
state_geo = f"us-states.json"
state_unemployment = f"US_Unemployment_Oct2012.csv"
state_data = pd.read_csv(state_unemployment)folium.Choropleth(
geo_data=state_geo,
name="choropleth",
data=state_data,
columns=["State", "Unemployment"],
key_on="feature.id",
fill_color="YlGn",
fill_opacity=0.7,
line_opacity=.1,
legend_name="Unemployment Rate (%)",
).add_to(m)folium.LayerControl().add_to(m)
# 保存
m.save('choropleth-map.html')
使用Folium的choropleth()進行繪制,結果如下。
31. 網格地圖
Hexbin地圖,美國大選投票經常看見。
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt# 讀取數據
file = "us_states_hexgrid.geojson.json"
geoData = gpd.read_file(file)
geoData['centroid'] = geoData['geometry'].apply(lambda x: x.centroid)mariageData = pd.read_csv("State_mariage_rate.csv")
geoData['state'] = geoData['google_name'].str.replace(' \(United States\)','')geoData = geoData.set_index('state').join(mariageData.set_index('state'))# 初始化
fig, ax = plt.subplots(1, figsize=(6, 4))# 繪圖
geoData.plot(
ax=ax,
column="y_2015",
cmap="BuPu",
norm=plt.Normalize(vmin=2, vmax=13),
edgecolor='black',
linewidth=.5
);# 不顯示坐標軸
ax.axis('off')# 標題, 副標題,作者
ax.annotate('Mariage rate in the US', xy=(10, 340), xycoords='axes pixels', horizontalalignment='left', verticalalignment='top', fontsize=14, color='black')
ax.annotate('Yes, people love to get married in Vegas', xy=(10, 320), xycoords='axes pixels', horizontalalignment='left', verticalalignment='top', fontsize=11, color='#808080')
ax.annotate('xiao F', xy=(400, 0), xycoords='axes pixels', horizontalalignment='left', verticalalignment='top', fontsize=8, color='#808080')# 每個網格
for idx, row in geoData.iterrows():
ax.annotate(
s=row['iso3166_2'],
xy=row['centroid'].coords[0],
horizontalalignment='center',
va='center',
color="white"
)# 添加顏色
sm = plt.cm.ScalarMappable(cmap='BuPu', norm=plt.Normalize(vmin=2, vmax=13))
fig.colorbar(sm, orientation="horizontal", aspect=50, fraction=0.005, pad=0 );# 顯示
plt.show()
使用geopandas和matplotlib進行繪制,結果如下。
32. 變形地圖
故名思義,就是形狀發生改變的地圖。
其中每個區域的形狀,會根據數值發生扭曲變化。
這里沒有相關的代碼示例,直接上個圖好了。
33. 連接映射地圖
連接地圖可以顯示地圖上幾個位置之間的連接關系。
航空上經常用到的飛線圖,應該是這個的升級版。
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd# 數據
cities = {
'city': ["Paris", "Melbourne", "Saint.Petersburg", "Abidjan", "Montreal", "Nairobi", "Salvador"],
'lon': [2, 145, 30.32, -4.03, -73.57, 36.82, -38.5],
'lat': [49, -38, 59.93, 5.33, 45.52, -1.29, -12.97]
}
df = pd.DataFrame(cities, columns=['city', 'lon', 'lat'])# 創建地圖
m = Basemap(llcrnrlon=-179, llcrnrlat=-60, urcrnrlon=179, urcrnrlat=70, projection='merc')
m.drawmapboundary(fill_color='white', linewidth=0)
m.fillcontinents(color='#f2f2f2', alpha=0.7)
m.drawcoastlines(linewidth=0.1, color="white")# 循環建立連接
for startIndex, startRow in df.iterrows():
for endIndex in range(startIndex, len(df.index)):
endRow = df.iloc[endIndex]
m.drawgreatcircle(startRow.lon, startRow.lat, endRow.lon, endRow.lat, linewidth=1, color='#69b3a2');# 添加城市名稱
for i, row in df.iterrows():
plt.annotate(row.city, xy=m(row.lon + 3, row.lat), verticalalignment='center')plt.show()
使用basemap繪制,結果如下。
34. 氣泡地圖
氣泡地圖,使用不同尺寸的圓來表示該地理坐標的數值。
import folium
import pandas as pd# 創建地圖對象
m = folium.Map(location=[20,0], tiles="OpenStreetMap", zoom_start=2)# 坐標點數據
data = pd.DataFrame({
'lon': [-58, 2, 145, 30.32, -4.03, -73.57, 36.82, -38.5],
'lat': [-34, 49, -38, 59.93, 5.33, 45.52, -1.29, -12.97],
'name': ['Buenos Aires', 'Paris', 'melbourne', 'St Petersbourg', 'Abidjan', 'Montreal', 'Nairobi', 'Salvador'],
'value': [10, 12, 40, 70, 23, 43, 100, 43]
}, dtype=str)# 添加氣泡
for i in range(0, len(data)):
folium.Circle(
location=[data.iloc[i]['lat'], data.iloc[i]['lon']],
popup=data.iloc[i]['name'],
radius=float(data.iloc[i]['value'])*20000,
color='crimson',
fill=True,
fill_color='crimson'
).add_to(m)# 保存
m.save('bubble-map.html')
使用Folium的Circle()進行繪制,結果如下。
35. 和弦圖
和弦圖表示若干個實體(節點)之間的流或連接。
每個實體(節點)有圓形布局外部的一個片段表示。
然后在每個實體之間繪制弧線,弧線的大小與流的關系成正比。
from chord import Chordmatrix = [
[0, 5, 6, 4, 7, 4],
[5, 0, 5, 4, 6, 5],
[6, 5, 0, 4, 5, 5],
[4, 4, 4, 0, 5, 5],
[7, 6, 5, 5, 0, 4],
[4, 5, 5, 5, 4, 0],
]names = ["Action", "Adventure", "Comedy", "Drama", "Fantasy", "Thriller"]# 保存
Chord(matrix, names).to_html("chord-diagram.html")
使用Chord庫進行繪制,結果如下。
36. 網狀圖
網狀圖顯示的是一組實體之間的連接關系。
每個實體由一個節點表示,節點之間通過線段連接。
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt# 創建數據
ind1 = [5, 10, 3, 4, 8, 10, 12, 1, 9, 4]
ind5 = [1, 1, 13, 4, 18, 5, 2, 11, 3, 8]
df = pd.DataFrame(
{'A': ind1, 'B': ind1 + np.random.randint(10, size=(10)), 'C': ind1 + np.random.randint(10, size=(10)),
'D': ind1 + np.random.randint(5, size=(10)), 'E': ind1 + np.random.randint(5, size=(10)), 'F': ind5,
'G': ind5 + np.random.randint(5, size=(10)), 'H': ind5 + np.random.randint(5, size=(10)),
'I': ind5 + np.random.randint(5, size=(10)), 'J': ind5 + np.random.randint(5, size=(10))})# 計算相關性
corr = df.corr()# 轉換
links = corr.stack().reset_index()
links.columns = ['var1', 'var2', 'value']# 保持相關性超過一個閾值, 刪除自相關性
links_filtered = links.loc[(links['value'] > 0.8) & (links['var1'] != links['var2'])]# 生成圖
G = nx.from_pandas_edgelist(links_filtered, 'var1', 'var2')# 繪制網絡
nx.draw(G, with_labels=True, node_color='orange', node_size=400, edge_color='black', linewidths=1, font_size=15)# 顯示
plt.show()
使用NetworkX庫進行繪制,結果如下。
37. 桑基圖
桑基圖是一種特殊的流圖。
它主要用來表示原材料、能量等如何從初始形式經過中間過程的加工、轉化到達最終形式。
Plotly可能是創建桑基圖的最佳工具,通過Sankey()在幾行代碼中獲得一個圖表。
import plotly.graph_objects as go
import json# 讀取數據
with open('sankey_energy.json') as f:
data = json.load(f)# 透明度
opacity = 0.4
# 顏色
data['data'][0]['node']['color'] = ['rgba(255,0,255, 0.8)' if color == "magenta" else color for color in data['data'][0]['node']['color']]
data['data'][0]['link']['color'] = [data['data'][0]['node']['color'][src].replace("0.8", str(opacity))
for src in data['data'][0]['link']['source']]fig = go.Figure(data=[go.Sankey(
valueformat=".0f",
valuesuffix="TWh",
# 點
node=dict(
pad=15,
thickness=15,
line=dict(color = "black", width = 0.5),
label=data['data'][0]['node']['label'],
color=data['data'][0]['node']['color']
),
# 線
link=dict(
source=data['data'][0]['link']['source'],
target=data['data'][0]['link']['target'],
value=data['data'][0]['link']['value'],
label=data['data'][0]['link']['label'],
color=data['data'][0]['link']['color']
))])fig.update_layout(title_text="Energy forecast for 2050<br>Source: Department of Energy & Climate Change, Tom Counsell via <a href='https://bost.ocks.org/mike/sankey/'>Mike Bostock</a>",
font_size=10)# 保持
fig.write_html("sankey-diagram.html")
使用Plotly庫進行繪制,結果如下。
38. 弧線圖
弧線圖是一種特殊的網絡圖。
由代表實體的節點和顯示實體之間關系的弧線組成的。
在弧線圖中,節點沿單個軸顯示,節點間通過圓弧線進行連接。
目前還不知道如何通過Python來構建弧線圖,不過可以使用R或者D3.js。
下面就來看一個通過js生成的弧線圖。
39. 環形布局關系圖
可視化目標之間的關系,可以減少復雜網絡下觀察混亂。
和弧線圖一樣,也只能通R或者D3.js繪制。
D3.js繪制的示例如下。
40. 動態圖表
動態圖表本質上就是顯示一系列靜態圖表。
可以描述目標從一種狀態到另一種狀態的變化。
import imageio
import pandas as pd
import matplotlib.pyplot as plt# 讀取數據
data = pd.read_csv('gapminderData.csv')
# 更改格式
data['continent'] = pd.Categorical(data['continent'])# 分辨率
dpi = 96filenames = []
# 每年的數據
for i in data.year.unique():
# 關閉交互式繪圖
plt.ioff() # 初始化
fig = plt.figure(figsize=(680 / dpi, 480 / dpi), dpi=dpi) # 篩選數據
subsetData = data[data.year == i] # 生成散點氣泡圖
plt.scatter(
x=subsetData['lifeExp'],
y=subsetData['gdpPercap'],
s=subsetData['pop'] / 200000,
c=subsetData['continent'].cat.codes,
cmap="Accent", alpha=0.6, edgecolors="white", linewidth=2) # 添加相關信息
plt.yscale('log')
plt.xlabel("Life Expectancy")
plt.ylabel("GDP per Capita")
plt.title("Year: " + str(i))
plt.ylim(0, 100000)
plt.xlim(30, 90) # 保存
filename = './images/' + str(i) + '.png'
filenames.append(filename)
plt.savefig(fname=filename, dpi=96)
plt.gca()
plt.close(fig)# 生成GIF動態圖表
with imageio.get_writer('result.gif', mode='I', fps=5) as writer:
for filename in filenames:
image = imageio.imread(filename)
writer.append_data(image)
以一個動態散點氣泡圖為例,
先用matplotlib繪制圖表圖片,再通過imageio生成GIF,結果如下。
好了,本期的分享就到此結束了。
其中使用到的可視化庫,大部分通過pip install即可完成安裝。
相關代碼及文件已上傳,評論區回復「可視化圖表」即可獲取。
有興趣的小伙伴,可以自行去實踐學習一下!
文作者:HelloGitHub-kalifun
圖表庫千萬個今天 HelloGitHub 給大家推薦個很有“特色”的圖表庫:一個手繪風格的 JS 圖表庫 —— Chart.xkcd,快收起你緊繃、嚴肅的面容讓我們一起看看用手繪風格展示數據的效果。
一、介紹
項目地址:https://github.com/timqian/chart.xkcd
Chart.xkcd 是一個圖表庫,可繪制“非精細”、“卡通”或“手繪”樣式的圖表。
效果是不是很可愛?那下面就跟著 HelloGitHub 發起的《講解開源項目》[1]的教程一起學習、上手使用起來吧!
二、快速入手
使用 Chart.xkcd 很容易,只需頁面中包含庫的引用和一個用于顯示圖表的 <svg> 節點即可。
2.1 代碼示例
先用一段簡短的代碼,讓大家了解下基本的參數和代碼的樣子,后面會有可運行的代碼示例片段供大家學習和使用 。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--將 SVG 元素直接嵌入 HTML 頁面中--> <svg class="line-chart"></svg> <!--引入 JS 庫--> <script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1.1/dist/chart.xkcd.min.js"></script> <script> //關鍵代碼塊 const svg=document.querySelector('.line-chart') new chartXkcd.Line(svg, { title: '', xLabel: '', yLabel: '', data: {...}, options: {}, }); </script> </body> </html>
2.2 參數說明
三、圖表類型
Chart.xkcd 支持多樣的圖表類型,下面將逐一講解和實現:折線圖、XY 圖、條形圖、圓餅/甜甜圈圖、雷達圖,實現的示例代碼完整可運行、注釋完整、包含參數說明。
tips:下文中的示例代碼均可直接運行,保存為 html 文件便可在本機查看效果。
3.1 折線圖
折線圖以折線形式顯示一系列數據點,它可以用于顯示趨勢數據或不同數據集的比較。
示例代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--將 SVG 元素直接嵌入 HTML 頁面中--> <svg class="line-chart"></svg> <!--引入 JS 庫--> <script src="https://cdn.jsdelivr.net/npm/chart.xkcd@1.1/dist/chart.xkcd.min.js"></script> <script> // querySelector() 方法返回文檔中匹配指定 CSS 選擇器的一個元素。獲取文檔中 class=".line-chart" 的元素。 const svg=document.querySelector('.line-chart'); // chartXkcd.Line 創建一個折線圖 const lineChart=new chartXkcd.Line(svg, { //圖表的標題 title: 'Monthly income of an indie developer', // 圖表的 x 標簽 xLabel: 'Month', // 圖表的 y 標簽 yLabel: '$ Dollors', // 需要可視化的數據 data: { // x 軸數據 labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], // y 軸數據 datasets: [{ // 第一組數據 label: 'Plan', data: [30, 70, 200, 300, 500, 800, 1500, 2900, 5000, 8000], }, { // 第二組數據 label: 'Reality', data: [0, 1, 30, 70, 80, 100, 50, 80, 40, 150], }], }, // 可選配置以自定義圖表的外觀 options: { // 自定義要在 y 軸上看到的刻度號(默認為 3) yTickCount: 3, // 指定要放置圖例的位置 legendPosition: chartXkcd.config.positionType.upLeft } }); </script> </body> </html>
參數說明
效果展示
3.2 XY 圖
XY 圖表用于通過指定點的 XY 坐標來繪制點,您也可以通過連接這些點來繪制 XY 折線圖。
示例代碼
<script> // querySelector() 方法返回文檔中匹配指定 CSS 選擇器的一個元素。獲取文檔中 class=".xy-chart" 的元素。 const svg=document.querySelector('.xy-chart'); //chartXkcd.XY 創建一個XY圖 new chartXkcd.XY(svg, { //圖表的標題 title: 'Pokemon farms', // 圖表的 x 標簽 xLabel: 'Coodinate', // 圖表的 y 標簽 yLabel: 'Count', // 需要可視化的數據 data: { datasets: [{ // 第一組數據 label: 'Pikachu', data: [{ x: 3, y: 10 }, { x: 4, y: 122 }, { x: 10, y: 100 }, { x: 1, y: 2 }, { x: 2, y: 4 }], }, { // 第二組數據 label: 'Squirtle', data: [{ x: 3, y: 122 }, { x: 4, y: 212 }, { x: -3, y: 100 }, { x: 1, y: 1 }, { x: 1.5, y: 12 }], }], }, options: { // 自定義要在 x 軸上看到的刻度號(默認為 3) xTickCount: 5, // 自定義要在 y 軸上看到的刻度號(默認為 3) yTickCount: 5, // 指定要放置圖例的位置 legendPosition: chartXkcd.config.positionType.upRight, // 用線連接點(默認 false) showLine: false, // 指定時間格式 timeFormat: undefined, // 更改點的大小(默認為 1) dotSize: 1, }, }); </script>
參數說明
效果展示
如果你想將這些點連接起來,讓數據對比更加明顯的話。請修改 showLine:true 再刷新頁面你就可以看到連線的效果了。
3.3 條形圖
條形圖提供了一種顯示以豎條表示的數據值的方式。
示例代碼
<script> // querySelector() 方法返回文檔中匹配指定 CSS 選擇器的一個元素。獲取文檔中 class=".bar-chart" 的元素。 const svg=document.querySelector('.bar-chart'); // chartXkcd.Bar 創建一個條形圖 const barChart=new chartXkcd.Bar(svg, { // 圖表的標題 title: 'github stars VS patron number', // xLabel: '', // optional // yLabel: '', // optional // 圖表數據 data: { labels: ['github stars', 'patrons'], datasets: [{ data: [100, 2], }], }, options: { // 自定義要在 y 軸上看到的刻度號(默認為 3) yTickCount: 2, }, }); </script>
參數說明
效果展示
3.4 圓餅/甜甜圈圖
餅圖廣泛得應用在各個領域,用于表示不同分類的占比情況,通過弧度大小來對比各種分類。餅圖通過將一個圓餅按照分類的占比劃分成多個區塊,整個圓餅代表數據的總量,每個區塊(圓弧)表示該分類占總體的比例大小,所有區塊(圓弧)的加和等于 100%。
示例代碼
<script> // querySelector() 方法返回文檔中匹配指定 CSS 選擇器的一個元素。獲取文檔中 class=".pie-chart" 的元素。 const svg=document.querySelector('.pie-chart'); // chartXkcd.Pie 創建一個圓餅圖 const pieChart=new chartXkcd.Pie(svg, { // 圖表的標題 title: 'What Tim made of', // 需要可視化的數據 data: { labels: ['a', 'b', 'e', 'f', 'g'], datasets: [{ data: [500, 200, 80, 90, 100], }], }, options: { // 指定空的餅圖半徑 innerRadius: 0.5, // 指定要放置圖例的位置 legendPosition: chartXkcd.config.positionType.upRight, }, }); </script>
參數說明
效果展示
3.5 雷達圖
雷達圖(Radar Chart)又被叫做蜘蛛網圖,適用于顯示三個或更多的維度的變量。雷達圖是以在同一點開始的軸上顯示的三個或更多個變量的二維圖表的形式來顯示多元數據的方法,其中軸的相對位置和角度通常是無意義的。
示例代碼
<script> // querySelector() 方法返回文檔中匹配指定 CSS 選擇器的一個元素。獲取文檔中 class=".radar-chart" 的元素。 const svg=document.querySelector('.radar-chart'); // chartXkcd.Radar 創建一個雷達圖 const radarChart=new chartXkcd.Radar(svg, { // 圖表的標題 title: 'Letters in random words', // 需要可視化的數據 data: { labels: ['c', 'h', 'a', 'r', 't'], datasets: [{ label: 'ccharrrt', data: [2, 1, 1, 3, 1], }, { label: 'chhaart', data: [1, 2, 2, 1, 1], }], }, options: { // 在圖表中顯示圖例 showLegend: true, // 點的大小 dotSize: 0.8, // 在每行附近顯示標簽 showLabels: true, // 指定要放置圖例的位置 legendPosition: chartXkcd.config.positionType.upRight, // unxkcdify: true, }, }); </script>
參數說明
效果展示
四、最后
以上就是講解的全部內容,相信教程至此 Chart.xkcd 庫的基本用法你已經基本掌握,后面就可以用來今天學到的東西,提高自己項目的顏值了。
有了 Chart.xkcd 讓數據可愛地展示出來并不難,快動手自己實現一個吧~
參考資料
[1]《講解開源項目》: https://github.com/HelloGitHub-Team/Article
[2]CHART.XKCD 官方文檔: https://timqian.com/chart.xkcd/
[3]CHART.XKCD 項目地址: https://github.com/timqian/chart.xkcd
『講解開源項目系列』——讓對開源項目感興趣的人不再畏懼、讓開源項目的發起者不再孤單。跟著我們的文章,你會發現編程的樂趣、使用和發現參與開源項目如此簡單。歡迎留言聯系我們、加入我們,讓更多人愛上開源、貢獻開源~
度地圖開放平臺功能強大,使用簡單,為地圖的自定義提供了非常方便的途徑!
本文以繪制一張全國機器輻射圖為例記錄其基本使用方法,效果如下圖:
圖中包括了帶圖標和文本的標注,連線以及圖例。
1.關于坐標
說到地圖,不得不說坐標。
我以為,GPS獲取經緯度之后,把經緯度丟給地圖就可以了。但那真的是自以為。
1.1 坐標系
來看看實際情況,以下是百度開發文檔里的描述:
目前國內主要有以下三種坐標系:
WGS84:為一種大地坐標系,也是目前廣泛使用的GPS全球衛星定位系統使用的坐標系。
GCJ02:又稱火星坐標系,是由中國國家測繪局制訂的地理信息系統的坐標系統。由WGS84坐標系經加密后的坐標系。
BD09:為百度坐標系,在GCJ02坐標系基礎上再次加密。其中bd09ll表示百度經緯度坐標,bd09mc表示百度墨卡托米制坐標。
非中國地區地圖,服務坐標統一使用WGS84坐標。
百度對外接口的坐標系為BD09坐標系,并不是GPS采集的真實經緯度,在使用百度地圖JavaScript API服務前,需先將非百度坐標通過坐標轉換接口轉換成百度坐標。
通過 GPS 獲取的為 WGS84,在百度地圖上使用前要轉換為 BD09,百度提供了相應的 api 進行坐標轉換,文檔地址:http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak=s1eeiQEfDF0WZfdfvLgHbG2Ru49UNCrn 返回結果: { status : 0, result : [ { x : 114.23074871003, y : 29.579084787993 } ] }
具體還可參考下這篇文章:https://www.cnblogs.com/yesicoo/p/4668642.html
1.2 坐標拾取器
如果坐標是靜態的,或測試用,可以直接通過百度地圖提供的“坐標拾取器”工具來獲取經緯度。
工具地址:http://api.map.baidu.com/lbsapi/getpoint/index.html
點哪就獲取哪的坐標,此坐標不用再轉換,復制過來即可以使用。
2. 開始應用
2.1 準備圖標
有好些站點可以下載圖標,如:https://easyicon.net,可以獲取一些圖標文件。至于商用的要求則要看看站點說明。
如下圖,這里準備總部與機器的圖標下載保存為 head.png、machine.png。
2.2 開啟百度地圖
地圖API的使用需要先申請一個 ak,為了體驗方便,這里已經申請了一個可以直接使用的 key,在頁面中可直接加入以下引用。
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=s1eeiQEfDF0WZfdfvLgHbG2Ru49UNCrn"></script>
使用以下語句,定義全局的地圖對象
// 百度地圖 API 功能對象 var map=null; if (BMap) { map=new BMap.Map("allmap"); // id=allmap 的容器內顯示 map.enableScrollWheelZoom(); }
2.2 標注:圖標與文本
標注使用 BMap.Marker,可以為其指定 Icon與Label。為了方便后續使用,本例定義以下函數,指定位置、圖標(本例中可用已經下載的圖標 head,machine)以及文本即可。
/** * 指定經緯度,圖標,標注文本 * 在地圖上添加標注 * longitude 經度 * latitude 緯度 * icon 圖標 * text 標注文本 **/ function addMarker(longitude, latitude, icon, text) { if (!map) return; var point=new BMap.Point(longitude, latitude); var myIcon=new BMap.Icon(icon + ".png", new BMap.Size(32, 32)); // 指定位置及標注的圖標 var marker=new BMap.Marker(point, { icon: myIcon }); // 創建標注 if(text){ var label=new BMap.Label(text, { offset: new BMap.Size(32, -16) }); marker.setLabel(label); } // 添加到地圖上 map.addOverlay(marker); }
2.3 連線
連線實際使用的是繪制多邊形的功能,只是當只指定了兩個點時,就是一根線。同樣,這里定義一個函數以方便直接調用。
/** * 指定起止經緯度,繪制連接線 * * longitudeFrom 經度 * latitudeFrom 緯度 * longitudeTo 經度 * latitudeTo 緯度 **/ function addLine(longitudeFrom, latitudeFrom, longitudeTo, latitudeTo) { if (!map) return; var pointFrom=new BMap.Point(longitudeFrom, latitudeFrom); var pointTo=new BMap.Point(longitudeTo, latitudeTo); // 可以指定多點連接,此處只考慮兩點 var line=new BMap.Polyline([pointFrom, pointTo], { strokeWeight:1, strokeOpacity:0.5, strokeColor:"red" }); // 添加到地圖上 map.addOverlay(line); }
2.4 圖例
圖例需要以地圖定義的控件方式來添加,在控件的 initialize 事件中完成 DOM 元素的生成即可,為了體現過程本身,以下函數把 DOM 的html文本作為參數,由外部靈活定義。
/** * 添加圖例 * 實質就是在地圖上添加自己的頁面元素 * * html 網頁元素 **/ function addLegend(html){ var LegendControl=function () { this.defaultAnchor=BMAP_ANCHOR_TOP_LEFT; this.defaultOffset=new BMap.Size(10, 10); } LegendControl.prototype=new BMap.Control(); LegendControl.prototype.initialize=function (map) { var le=$(html)[0]; map.getContainer().appendChild(le); return le; }; var legendCtrl=new LegendControl(); map.addControl(legendCtrl); }
2.5 綜合
有了以上函數,綜合起來就流程清晰了。以下坐標,均通過坐標拾取器獲取。
// 機器類:經度,緯度,名稱 function Machine(longitude, latitude, name){ this.longitude=longitude; this.latitude=latitude; this.name=name; } // 確定地圖的中心位置與縮放級別 var center=new BMap.Point(110.423997,31.40979); map.centerAndZoom(center, 6); // 級別 6,跨省視圖 // 添加圖例,自由寫 html addLegend("<div style='font-size:12px; color:gray; width:140px; padding:5px; background:white; text-align:center; border:solid 1px gray;'>總部:<img src='head.png' style='width:16px; vertical-align:middle;' /> 設備:<img src='machine.png' style='width:16px; vertical-align:middle;' /></div>"); // 總部位置 var head={ longitude : 112.918702343957, latitude : 28.30070516 }; addMarker(head.longitude, head.latitude, 'head', '總部'); // 所有機器位置 var machineList=[ new Machine(114.876143,38.113315,'石家莊'), new Machine(112.521289,37.822014,'太原'), new Machine(108.989008,34.328175,'西安'), new Machine(117.230997,31.881961,'合肥'), new Machine(103.984944,30.553819,'成都'), new Machine(108.400295,22.862517,'南寧'), new Machine(113.257181,23.169067,'廣州'), new Machine(120.174565,30.298715,'杭州'), new Machine(102.881106,24.959705,'昆明') ]; // 添加所有機器并連線 for(var i=0; i<machineList.length; i++){ addMarker(machineList[i].longitude, machineList[i].latitude, 'machine', machineList[i].name); addLine(head.longitude, head.latitude, machineList[i].longitude, machineList[i].latitude); }
3. 結語
本文完整代碼可從此處下載:
https://github.com/triplestudio/helloworld/blob/master/baidu_map_demo.html
在此基礎上,可以根據需要進一步擴展功能,具體參考百度地圖開放平臺開發文檔:
http://lbsyun.baidu.com/
*請認真填寫需求信息,我們會在24小時內與您取得聯系。