plotly功能比较全,传统如matplot更多的是面向基础绘图组件的编辑。大部分情况下,我们更在乎的是可视化展现效果,因此plotly这种快速,漂亮,简单的可视化解决方案挺不错。
但是呢,plotly也会有比较坑的地方,比如你要注册账户生成apikey,使用前必须写:
plotly.tools.set_credentials_file(username='user_name', api_key='KC2kwJWZXjfSJ65bhCvc')
还有个比较坑的是官方绘图写的是
py.iplot(data, filename='basic-scatter')
但实际上会报错,要改成py.plot才能绘制成功。成功了会保存在你的账号里,生成utl可以分享。分享的效果是比较好的。
一 基础绘图入门
点图
import numpy as np
import pandas as pd
import plotly.plotly as py
import plotly
import plotly.graph_objs as gp
rand_x=np.random.randn(1000)
rand_y=np.random.randn(1000)
plotly.tools.set_credentials_file(username='user_name', api_key='KC2kwJWZXjfSJ65bhCvc')
#生成一个trace,要求有x,y,绘图模式
trace=gp.Scatter(
x=rand_x,
y=rand_y,
mode='markers'
)
data=[trace]
ts=py.plot(data,filename='basic-scatter')
不需要打印,浏览器会自己打开页面:https://plot.ly/~junshan2009/0/#plot (陌生人是否能看需要你设权限)
线图
mode = 'lines'
或者
mode = 'lines+markers'
参见:这里顺便把trace3生成了一个次坐标轴,因为其数据太大了。
import plotly
import plotly.plotly as pl
import plotly.graph_objs as go
import pandas as pd
plotly.tools.set_credentials_file(username='user_name', api_key='KC2kwJWZXjfSJ65bhCvc')
df = pd.read_csv('jine2019.csv')
y = df['dt'][:-1]
x1 = df['uus'][:-1]
x2 = df['ddl'][:-1]
x3 = df['jine'][:-1]
trace1 = go.Scatter(
x=y,
y=x1,
mode='lines+markers',
name='用户数'
)
trace2 = go.Scatter(
x=y,
y=x2,
mode='lines',
name='订单量'
)
trace3 = go.Scatter(
x=y,
y=x3,
mode='markers',
name='金额',
xaxis='x',
yaxis='y2' #标注一个y轴
)
data = [trace1, trace2, trace3]
layout=go.Layout(
yaxis2=dict(anchor='x',overlaying='y',side='right') #设置y轴格式
)
fig=go.Figure(data=data,layout=layout)
pl.plot(fig, filename='figure1')
plotly生成的结果会保存在链接的网页上面,免费用户只能保存25个figure,但是时间长了链接会挂掉,所以还是建议离线存一下figure
如何调节图像中的格式,比如点的颜色,大小呢?
import plotly
import plotly.plotly as pl
import plotly.graph_objs as go
import pandas as pd
import numpy as np
plotly.tools.set_credentials_file(username='user_name', api_key='KC2kwJWZXjfSJ65bhCvc')
df = pd.read_csv('jine2019.csv')
y = df['dt'][:-1]
x1 = df['uus'][:-1]
x2 = df['ddl'][:-1]
x3 = df['jine'][:-1]
trace1 = go.Scatter(
x=y,
y=x1 - 100,
mode='markers',
name='用户数',
marker=dict( # 调节marker的属性
size=10, # 标点大小
color='#90EE90', # 点的颜色 支持rgb格式和十六进制色彩
line=dict(
width=2,
color='rgb(0,0,0)'
)
)
)
trace2 = go.Scatter(
x=y,
y=x2,
mode='markers',
name='订单量',
marker=dict(
size=20,
color=np.random.randn(500),
colorscale='Viridis',
showscale=True
)
)
data = [trace1, trace2]
layout = dict(
title='调节布局',
# yaxis=dict(zeroline=False),
xaxis=dict(zeroline=False)
)
fig = go.Figure(data=data, layout=layout)
pl.plot(fig, filename='figure1')
注意,指定filename的时候,不改变会在plotly的网站上覆盖上个图像。plotly的色彩支持十六位和rgb两种格式,并且可以和数字相互打通。
二 基本的图样介绍
饼图
感觉plot画饼图不太友好,一股浓浓的echarts风格。
import plotly
import plotly.plotly as py
plotly.tools.set_credentials_file(username='user_name', api_key='KC2kwJWZXjfSJ65bhCvc')
fig = {
"data": [
{
"values": [16, 15, 12, 6, 5, 4, 42],
"labels": [
"US",
"China",
"European Union",
"Russian Federation",
"Brazil",
"India",
"Rest of World"
],
"domain": {"x": [0, .48]},
"name": "GHG Emissions",
"hoverinfo": "label+percent+name",
"hole": .4,
"type": "pie"
},
{
"values": [27, 11, 25, 8, 1, 3, 25],
"labels": [
"US",
"China",
"European Union",
"Russian Federation",
"Brazil",
"India",
"Rest of World"
],
"text": ["CO2"],
"textposition": "inside",
"domain": {"x": [.52, 1]},
"name": "CO2 Emissions",
"hoverinfo": "label+percent+name",
"hole": .4,
"type": "pie"
}],
"layout": {
"title": "Global Emissions 1990-2011",
"annotations": [
{
"font": {
"size": 20
},
"showarrow": False,
"text": "GHG",
"x": 0.20,
"y": 0.5
},
{
"font": {
"size": 20
},
"showarrow": False,
"text": "CO2",
"x": 0.8,
"y": 0.5
}
]
}
}
py.plot(fig, filename='pie_bkg_demo')
但是交互效果还是挺不错的。
表格
plot支持基本的表格,而且还可以按照表格内的数字值给表格绘色,类似于excel的条件格式。
trace = go.Table(
header=dict(values=['A Scores', 'B Scores'],
line = dict(color='#7D7F80'),
fill = dict(color='#a1c3d1'),
align = ['left'] * 5),
cells=dict(values=[[100, 90, 80, 90],
[95, 85, 75, 95]],
line = dict(color='#7D7F80'),
fill = dict(color='#EDFAFF'),
align = ['left'] * 5))
layout = dict(width=500, height=300)
data = [trace]
fig = dict(data=data, layout=layout)
py.iplot(fig, filename = 'styled_table')
py.plot(fig, filename='pie_bkg_demo')
交互效果不错,虽然是表格,但是列可以手动拖拽,对可视化感兴趣的同学可以记住plot这个个性的功能。
三 绘制地图
plot绘制地图需要注册一个mapbox的账户(https://account.mapbox.com/),还需要自己生成一个token,所以感觉非常不方便。
这里只做介绍,感兴趣的同学可以自己去研究一下。
mapbox_access_token = 'pk.eyJ1Ijt1w4Gse_2eZ8c1pSlqjylw'
data = [
go.Scattermapbox(
lat=['38.91427', '38.91538', '38.91458',
'38.92239', '38.93222', '38.90842',
'38.91931', '38.93260', '38.91368',
'38.88516', '38.921894', '38.93206',
'38.91275'],
lon=['-77.02827', '-77.02013', '-77.03155', # 数据量大的话可以使用pandas读列
'-77.04227', '-77.02854', '-77.02419',
'-77.02518', '-77.03304', '-77.04509',
'-76.99656', '-77.042438', '-77.02821',
'-77.01239'],
mode='markers',
marker=dict(
size=9
),
text=["The coffee bar", "Bistro Bohem", "Black Cat",
"Snap", "Columbia Heights Coffee", "Azi's Cafe",
"Blind Dog Cafe", "Le Caprice", "Filter",
"Peregrine", "Tryst", "The Coupe",
"Big Bear Cafe"],
)
]
layout = go.Layout(
autosize=True,
hovermode='closest',
mapbox=dict(
accesstoken=mapbox_access_token,
bearing=0,
center=dict( #打开地图默认的聚焦点
lat=38.92,
lon=-77.07
),
pitch=0,
zoom=10
),
)
fig = dict(data=data, layout=layout)
pl.plot(fig, filename='plot_map')
四 绘制空间网络图
绘制空间网络图需要igraph模块,使用anconda的一般都自带这个模块。但是python里面会有两个igraph模块,执行的时候会报错(版本错误,建议升级jgraph),这个时候需要卸载两个igraph
pip3 uninstall igraph
pip3 uninstall python_igraph
尤其是window平台,pip官方列表还没有适配python3的igraph,需要自己去下载适用的igraph版本。
推荐一个神奇的网站: https://www.lfd.uci.edu/~gohlke/pythonlibs/#python-igraph
下载对应你python版本的pycairo和igraph 。下载到python下面的Script文件夹下面安装
pip3 install ****.whl
安装好之后就可以正常使用igraph了。
import json as js
import urllib3 as url
import urllib.request as rqt
import igraph as ig
import plotly
import plotly.plotly as ply
import plotly.graph_objs as go
plotly.tools.set_credentials_file(username='xxx', api_key='KC2kwJWZXjfSJ65bhCvc')
data = []
url = "https://raw.githubusercontent.com/plotly/datasets/master/miserables.json"
s = rqt.urlopen(url).read().decode('utf8')
data = js.loads(s)
n = len(data['nodes'])
l = len(data['links'])
edge = [(data['links'][k]['source'], data['links'][k]['target']) for k in range(l)] # 生成igraph的标准格式包
G = ig.Graph(edge, directed=False)
labels = []
group = []
for node in data['nodes']:
labels.append(node['name'])
group.append(node['group'])
layt = G.layout('kk', dim=3)
# 下面把igraph的数据转变格式
Xn=[layt[k][0] for k in range(n)]# x-coordinates of nodes
Yn=[layt[k][1] for k in range(n)]# y-coordinates
Zn=[layt[k][2] for k in range(n)]# z-coordinates
Xe=[]
Ye=[]
Ze=[]
for e in edge:
Xe+=[layt[e[0]][0],layt[e[1]][0], None]# x-coordinates of edge ends
Ye+=[layt[e[0]][1],layt[e[1]][1], None]
Ze+=[layt[e[0]][2],layt[e[1]][2], None]
# 生成Scatter
trace1=go.Scatter3d(x=Xe,
y=Ye,
z=Ze,
mode='lines',
line=dict(color='rgb(125,125,125)', width=1),
hoverinfo='none'
)
trace2=go.Scatter3d(x=Xn,
y=Yn,
z=Zn,
mode='markers',
name='actors',
marker=dict(symbol='circle',
size=6,
color=group,
colorscale='Viridis',
line=dict(color='rgb(50,50,50)', width=0.5)
),
text=labels,
hoverinfo='text'
)
axis=dict(showbackground=False,
showline=False,
zeroline=False,
showgrid=False,
showticklabels=False,
title=''
)
layout = go.Layout(
title="this is title",
width=1000,
height=1000,
showlegend=False,
scene=dict(
xaxis=dict(axis),
yaxis=dict(axis),
zaxis=dict(axis),
),
margin=dict(
t=100
),
hovermode='closest',
annotations=[
dict(
showarrow=False,
text="Data source: [1] miserables.json",
xref='paper',
yref='paper',
x=0,
y=0.1,
xanchor='left',
yanchor='bottom',
font=dict(
size=14
)
)
],
)
data=[trace1,trace2]
fig=go.Figure(data=data,layout=layout)
ply.plot(fig,filename='3d_marker_bkg')
输出格式是个3d的交互图,可以拖拽