如何更改Plotly子图的大小和间距?
如何调整行之间的间距(比如增加前两行和最后两行之间的空间)以及图表的大小(比如让饼图变大)呢?
在我的例子中,我想用 plotly 的 FigureWidget
和 make_subplots
来可视化来自Telco 客户流失数据集(下载 176kB)的多个数据列。
这段代码会循环遍历8列数据,为每一列添加一个饼图和一个条形图。
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Read data
df = pd.read_csv("./WA_Fn-UseC_-Telco-Customer-Churn.csv")
df['SeniorCitizen'] = df['SeniorCitizen'].map({0: 'No', 1: 'Yes'})
# Define subplot titles and data columns
data_cols = ['PhoneService' ,'MultipleLines' ,'InternetService' ,'OnlineBackup' ,'DeviceProtection' ,'TechSupport' ,'StreamingTV' ,'StreamingMovies']
titles = ['Phone Service' ,'Multiple Lines' ,'Internet Service' ,'Online Backup' ,'Device Protection' ,'Tech Support' ,'Streaming TV' ,'Streaming Movies']
fig = go.FigureWidget(make_subplots(rows=4, cols=4, specs=[
[{'type':'domain'}, {'type':'domain'}, {'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}, {'type':'xy'}, {'type':'xy'}],
[{'type':'domain'}, {'type':'domain'}, {'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}, {'type':'xy'}, {'type':'xy'}]]))
row, col = 1, 0
for i, (title, data_col) in enumerate(zip(titles, data_cols)):
row, col = divmod(i, 4)
row = row * 2
# Get value counts for pie chart
value_counts = df[data_col].value_counts()
# Create pie chart trace and add to subplot
pie_chart = go.Pie(labels=value_counts.index, values=value_counts.to_numpy(), name=title, title=title)
fig.add_trace(pie_chart, row=row+1, col=col+1)
# get churn rates
churn_counts = df.groupby([data_col, 'Churn'])['Churn'].count().unstack()
# Create stacked bar charts
t1 = go.Bar(name='Churn (yes)', x=churn_counts['Yes'].index, y=churn_counts['Yes'])
t2 = go.Bar(name='Churn (no)', x=churn_counts['No'].index, y=churn_counts['No'], marker_color='indianred')
fig.add_trace(t1, row=row+2, col=col+1)
fig.add_trace(t2, row=row+2, col=col+1)
fig.update_layout(title="Distribution of Customer Services", barmode='stack', showlegend=False)
fig.show()
编辑:即使将列数减少到两个,这个问题也没有解决。这是在一个大宽屏上的图表:
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Read data
df = pd.read_csv("./WA_Fn-UseC_-Telco-Customer-Churn.csv")
df['SeniorCitizen'] = df['SeniorCitizen'].map({0: 'No', 1: 'Yes'})
# Define subplot titles and data columns
data_cols = ['PhoneService' ,'MultipleLines' ,'InternetService' ,'OnlineBackup' ,'DeviceProtection' ,'TechSupport' ,'StreamingTV' ,'StreamingMovies']
titles = ['Phone Service' ,'Multiple Lines' ,'Internet Service' ,'Online Backup' ,'Device Protection' ,'Tech Support' ,'Streaming TV' ,'Streaming Movies']
fig = go.FigureWidget(make_subplots(rows=8, cols=2, specs=[
[{'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}],
[{'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}],
[{'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}],
[{'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}]]))
row, col = 1, 0
for i, (title, data_col) in enumerate(zip(titles, data_cols)):
row, col = divmod(i, 2)
row = row * 2
# Get value counts for pie chart
value_counts = df[data_col].value_counts()
# Create pie chart trace and add to subplot
pie_chart = go.Pie(labels=value_counts.index, values=value_counts.to_numpy(), name=title, title=title)
fig.add_trace(pie_chart, row=row+1, col=col+1)
# get churn rates
churn_counts = df.groupby([data_col, 'Churn'])['Churn'].count().unstack()
# Create stacked bar charts
t1 = go.Bar(name='Churn (yes)', x=churn_counts['Yes'].index, y=churn_counts['Yes'])
t2 = go.Bar(name='Churn (no)', x=churn_counts['No'].index, y=churn_counts['No'], marker_color='indianred')
fig.add_trace(t1, row=row+2, col=col+1)
fig.add_trace(t2, row=row+2, col=col+1)
fig.update_layout(title="Distribution of Customer Services", barmode='stack', showlegend=False)
fig.show()
1 个回答
0
你可以通过 vertical_spacing
和 horizontal_spacing
这两个参数来调整行和列之间的间距。它们的值可以是0到 1/(size -1)
之间的小数。找到适合你的最佳值可能需要一些尝试。为了让图表在整个图形中占据更大的空间,你可以在 fig.update_layout
的调用中更新 margin
参数。四个边的设置用一个字典来表示,字典的键分别是: t
(上)、b
(下)、l
(左)和 r
(右)。
下面的代码是你原始代码的一个修改版,使用了这些参数。
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Read data
df = pd.read_csv("C:/Users/joost/Downloads/WA_Fn-UseC_-Telco-Customer-Churn.csv")
df['SeniorCitizen'] = df['SeniorCitizen'].map({0: 'No', 1: 'Yes'})
# Define subplot titles and data columns
data_cols = ['PhoneService' ,'MultipleLines' ,'InternetService' ,'OnlineBackup' ,'DeviceProtection' ,'TechSupport' ,'StreamingTV' ,'StreamingMovies']
titles = ['Phone Service' ,'Multiple Lines' ,'Internet Service' ,'Online Backup' ,'Device Protection' ,'Tech Support' ,'Streaming TV' ,'Streaming Movies']
hor_space = 0.02
ver_space = 0.02
fig = go.FigureWidget(make_subplots(rows=4,
cols=4,
specs=[[{'type':'domain'}, {'type':'domain'}, {'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}, {'type':'xy'}, {'type':'xy'}],
[{'type':'domain'}, {'type':'domain'}, {'type':'domain'}, {'type':'domain'}],
[{'type':'xy'}, {'type':'xy'}, {'type':'xy'}, {'type':'xy'}]
],
horizontal_spacing=hor_space, # in range 0 to 1/(cols-1)
vertical_spacing=ver_space # in range 0 to 1/(rows-1)
)
)
row, col = 1, 0
for i, (title, data_col) in enumerate(zip(titles, data_cols)):
row, col = divmod(i, 4)
row = row * 2
# Get value counts for pie chart
value_counts = df[data_col].value_counts()
# Create pie chart trace and add to subplot
pie_chart = go.Pie(labels=value_counts.index, values=value_counts.to_numpy(), name=title, title=title)
fig.add_trace(pie_chart, row=row+1, col=col+1)
# get churn rates
churn_counts = df.groupby([data_col, 'Churn'])['Churn'].count().unstack()
# Create stacked bar charts
t1 = go.Bar(name='Churn (yes)', x=churn_counts['Yes'].index, y=churn_counts['Yes'])
t2 = go.Bar(name='Churn (no)', x=churn_counts['No'].index, y=churn_counts['No'], marker_color='indianred')
fig.add_trace(t1, row=row+2, col=col+1)
fig.add_trace(t2, row=row+2, col=col+1)
fig.update_layout(title="Distribution of Customer Services",
barmode='stack',
showlegend=False,
margin={"l":25,
"r":25,
"t":25,
"b":25}
)
fig.show()
以下是一些来自plotly文档的背景信息: