如何使用 Plotly 制作带滑块的等值线图?
How to make a choropleth map with a slider using Plotly?
我正在重新创建 example choropleth and trying to add a slider that, when dragged, would change from year to year. Another user asked a similar question but they didn't receive a reply. I did some more searching and found an example,用户在其中生成额外年份的随机值并创建了一个滑块,但它位于 JavaScript 中,我不确定如何将其转换为 Python。
这是 JavaScript 中的代码:
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv', function(err, rows){
function unpack(rows, key) {
return rows.map(function(row) { return row[key]; });
}
var randomize = z => z.map(d => Math.pow(Math.random(), 2) * 30000);
var data = unpack(rows, 'total exports');
var frames = [{
data: [{z: unpack(rows, 'total exports')}],
traces: [0],
name: '1990',
layout: {title: '1990 US Agriculture Exports by State'}
}, {
data: [{z: randomize(data)}],
traces: [0],
name: '1995',
layout: {title: '1995 US Agriculture Exports by State'}
}, {
data: [{z: randomize(data)}],
traces: [0],
name: '2000',
layout: {title: '2000 US Agriculture Exports by State'}
}, {
data: [{z: randomize(data)}],
traces: [0],
name: '2005',
layout: {title: '2005 US Agriculture Exports by State'}
}]
var data = [{
type: 'choropleth',
locationmode: 'USA-states',
locations: unpack(rows, 'code'),
z: unpack(rows, 'total exports'),
text: unpack(rows, 'state'),
zmin: 0,
zmax: 17000,
colorscale: [
[0, 'rgb(242,240,247)'], [0.2, 'rgb(218,218,235)'],
[0.4, 'rgb(188,189,220)'], [0.6, 'rgb(158,154,200)'],
[0.8, 'rgb(117,107,177)'], [1, 'rgb(84,39,143)']
],
colorbar: {
title: 'Millions USD',
thickness: 0.2
},
marker: {
line:{
color: 'rgb(255,255,255)',
width: 2
}
}
}];
var layout = {
title: '1990 US Agriculture Exports by State',
geo:{
scope: 'usa',
showlakes: true,
lakecolor: 'rgb(255,255,255)'
},
xaxis: {autorange: false},
yaxis: {autorange: false},
sliders: [{
currentvalue: {
prefix: 'Year: ',
},
steps: frames.map(f => ({
label: f.name,
method: 'animate',
args: [[f.name], {frame: {duration: 0}}]
}))
}]
};
Plotly.plot('graph', {
data: data,
layout: layout,
frames: frames,
config: {showLink: false}
});
});
Python有没有办法做到这一点?
下面的代码实际上是 choropleth example for Python and the sliders 代码的精简版。
根据第一个数据创建随机数据,每个滑块条目显示数据列表的不同部分。
import pandas as pd
import plotly
import numpy as np
plotly.offline.init_notebook_mode()
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv')
data = [dict(type='choropleth',
locations = df['code'].astype(str),
z=df['total exports'].astype(float),
locationmode='USA-states')]
# let's create some additional, random data
for i in range(5):
data.append(data[0].copy())
data[-1]['z'] = data[0]['z'] * np.random.rand(*data[0]['z'].shape)
# let's create the steps for the slider
steps = []
for i in range(len(data)):
step = dict(method='restyle',
args=['visible', [False] * len(data)],
label='Year {}'.format(i + 1980))
step['args'][1][i] = True
steps.append(step)
sliders = [dict(active=0,
pad={"t": 1},
steps=steps)]
layout = dict(geo=dict(scope='usa',
projection={'type': 'albers usa'}),
sliders=sliders)
fig = dict(data=data,
layout=layout)
plotly.offline.iplot(fig)
我正在重新创建 example choropleth and trying to add a slider that, when dragged, would change from year to year. Another user asked a similar question but they didn't receive a reply. I did some more searching and found an example,用户在其中生成额外年份的随机值并创建了一个滑块,但它位于 JavaScript 中,我不确定如何将其转换为 Python。
这是 JavaScript 中的代码:
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv', function(err, rows){
function unpack(rows, key) {
return rows.map(function(row) { return row[key]; });
}
var randomize = z => z.map(d => Math.pow(Math.random(), 2) * 30000);
var data = unpack(rows, 'total exports');
var frames = [{
data: [{z: unpack(rows, 'total exports')}],
traces: [0],
name: '1990',
layout: {title: '1990 US Agriculture Exports by State'}
}, {
data: [{z: randomize(data)}],
traces: [0],
name: '1995',
layout: {title: '1995 US Agriculture Exports by State'}
}, {
data: [{z: randomize(data)}],
traces: [0],
name: '2000',
layout: {title: '2000 US Agriculture Exports by State'}
}, {
data: [{z: randomize(data)}],
traces: [0],
name: '2005',
layout: {title: '2005 US Agriculture Exports by State'}
}]
var data = [{
type: 'choropleth',
locationmode: 'USA-states',
locations: unpack(rows, 'code'),
z: unpack(rows, 'total exports'),
text: unpack(rows, 'state'),
zmin: 0,
zmax: 17000,
colorscale: [
[0, 'rgb(242,240,247)'], [0.2, 'rgb(218,218,235)'],
[0.4, 'rgb(188,189,220)'], [0.6, 'rgb(158,154,200)'],
[0.8, 'rgb(117,107,177)'], [1, 'rgb(84,39,143)']
],
colorbar: {
title: 'Millions USD',
thickness: 0.2
},
marker: {
line:{
color: 'rgb(255,255,255)',
width: 2
}
}
}];
var layout = {
title: '1990 US Agriculture Exports by State',
geo:{
scope: 'usa',
showlakes: true,
lakecolor: 'rgb(255,255,255)'
},
xaxis: {autorange: false},
yaxis: {autorange: false},
sliders: [{
currentvalue: {
prefix: 'Year: ',
},
steps: frames.map(f => ({
label: f.name,
method: 'animate',
args: [[f.name], {frame: {duration: 0}}]
}))
}]
};
Plotly.plot('graph', {
data: data,
layout: layout,
frames: frames,
config: {showLink: false}
});
});
Python有没有办法做到这一点?
下面的代码实际上是 choropleth example for Python and the sliders 代码的精简版。
根据第一个数据创建随机数据,每个滑块条目显示数据列表的不同部分。
import pandas as pd
import plotly
import numpy as np
plotly.offline.init_notebook_mode()
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv')
data = [dict(type='choropleth',
locations = df['code'].astype(str),
z=df['total exports'].astype(float),
locationmode='USA-states')]
# let's create some additional, random data
for i in range(5):
data.append(data[0].copy())
data[-1]['z'] = data[0]['z'] * np.random.rand(*data[0]['z'].shape)
# let's create the steps for the slider
steps = []
for i in range(len(data)):
step = dict(method='restyle',
args=['visible', [False] * len(data)],
label='Year {}'.format(i + 1980))
step['args'][1][i] = True
steps.append(step)
sliders = [dict(active=0,
pad={"t": 1},
steps=steps)]
layout = dict(geo=dict(scope='usa',
projection={'type': 'albers usa'}),
sliders=sliders)
fig = dict(data=data,
layout=layout)
plotly.offline.iplot(fig)