3 回答

TA貢獻1853條經驗 獲得超9個贊
我認為有一種更靈活的方法可以使用它,plotly.express特別是如果您不想定義顏色。
這個想法是正確地轉換數據。
數據
import pandas as pd
df = pd.DataFrame({1991:[10,100,50], 1992:[14,30,22], 1993:[16,70,30], 1994:[18,85,65], 1995:[20,30,70], 1996:[42,42,66], 1997:[64,64,60]})
df.index = ['US','JAPAN','CN']
df = df.T.unstack()\
? ? ? .reset_index()\
? ? ? .rename(columns={"level_0": "country",
? ? ? ? ? ? ? ? ? ? ? ?"level_1": "year",
? ? ? ? ? ? ? ? ? ? ? ?0: "n"})
print(df)
? ?country? year? ? n
0? ? ? ?US? 1991? ?10
1? ? ? ?US? 1992? ?14
2? ? ? ?US? 1993? ?16
3? ? ? ?US? 1994? ?18
4? ? ? ?US? 1995? ?20
5? ? ? ?US? 1996? ?42
6? ? ? ?US? 1997? ?64
7? ? JAPAN? 1991? 100
8? ? JAPAN? 1992? ?30
9? ? JAPAN? 1993? ?70
10? ?JAPAN? 1994? ?85
11? ?JAPAN? 1995? ?30
12? ?JAPAN? 1996? ?42
13? ?JAPAN? 1997? ?64
14? ? ? CN? 1991? ?50
15? ? ? CN? 1992? ?22
16? ? ? CN? 1993? ?30
17? ? ? CN? 1994? ?65
18? ? ? CN? 1995? ?70
19? ? ? CN? 1996? ?66
20? ? ? CN? 1997? ?60
使用plotly.express
現在您的數據是長格式,您可以使用plotly.express如下
import plotly.express as px
fig = px.scatter(df,
? ? ? ? ? ? ? ? ?x="year",
? ? ? ? ? ? ? ? ?y="country",
? ? ? ? ? ? ? ? ?size="n",
? ? ? ? ? ? ? ? ?color="country",
? ? ? ? ? ? ? ? ?text="n",
? ? ? ? ? ? ? ? ?size_max=50 # you need this otherwise the bubble are too small
? ? ? ? ? ? ? ? )
fig.update_layout(plot_bgcolor='rgb(10, 10, 10)',??
? ? ? ? ? ? ? ? ? paper_bgcolor='rgb(20, 55, 100)',??
? ? ? ? ? ? ? ? ? font={'size': 15,
? ? ? ? ? ? ? ? ? ? ? ? 'family': 'sans-serif',
? ? ? ? ? ? ? ? ? ? ? ? 'color': 'rgb(255, 255, 255)'
? ? ? ? ? ? ? ? ? ? ? ?},
? ? ? ? ? ? ? ? ? width=1000,
? ? ? ? ? ? ? ? ? height=500,
? ? ? ? ? ? ? ? ? xaxis=dict(title='Output of grapes per year in selected countries', ),??
? ? ? ? ? ? ? ? ? showlegend=False,
? ? ? ? ? ? ? ? ? margin=dict(l=100, r=100, t=100, b=100),
? ? ? ? ? ? ? ? ? hovermode = False,)
# Uncomment this if you don't wont country as yaxis title
# fig.layout.yaxis.title.text = None
fig.show()

TA貢獻1824條經驗 獲得超6個贊
我應該指出,如果您將原始數據附加為文本或可以更輕松地復制和粘貼的內容,那么您的代碼將更具可重復性。但是,無論如何,我仍然可以回答您的問題并為您指出正確的方向。
您應該做的是使用循環,并從查看行開始data = [trace0, trace1, trace2]。正如您所注意到的,如果您有 100 個國家/地區而不是 3 個國家/地區,此方法將無法擴展。
相反,您可以data使用列表理解將其創建為列表,并更新每個跟蹤中發生更改的部分。trace0除了國家/地區、值和顏色之外, 、trace1、trace2沒有太大區別。為了向您展示我的意思,我使用 DataFrame 重新創建了您的數據,然后創建了包含您的國家/地區和顏色的單獨列表。
# Version 2 could read data from .xlsx file.
import plotly as py
import plotly.graph_objs as go
import openpyxl
# wb = openpyxl.load_workbook(('grape output.xlsx'))
# sheet = wb['Sheet1']
# row_max = sheet.max_row
# col_max = sheet.max_column
# l=[]
# for row_n in range(row_max-1):
# l.append([])
# for col_n in range(col_max-1):
# l[row_n].append(sheet.cell(row=row_n+2, column=col_n+2).value)
import pandas as pd
df = pd.DataFrame({1991:[10,100,50], 1992:[14,30,22], 1993:[16,70,30], 1994:[18,85,65], 1995:[20,30,70], 1996:[42,42,66], 1997:[64,64,60]})
df.index = ['US','JAPAN','CN']
colors = ['rgb(150,204,90)','rgb(255, 130, 71)','rgb(255, 193, 37)']
data = [go.Scatter(
x=df.columns,
y=[country]*len(df.columns),
mode='markers+text',
marker=dict(
color=colors[num],
size= df.loc[country],
showscale = False,
),
text=list(map(str, df.loc[country])),
textposition='middle center',
)
for num, country in enumerate(df.index)
]
layout = go.Layout(plot_bgcolor='rgb(10, 10, 10)',
paper_bgcolor='rgb(20, 55, 100)',
font={
'size': 15,
'family': 'sans-serif',
'color': 'rgb(255, 255, 255)'
},
width=1000,
height=500,
xaxis=dict(title='Output of grapes per year in US, JAPAN and CN', ),
showlegend=False,
margin=dict(l=100, r=100, t=100, b=100),
hovermode = False,
)
# data = [trace0, trace1, trace2]
fig = go.Figure(data=data, layout=layout)
fig.show()
# py.offline.init_notebook_mode()
# py.offline.plot(fig, filename='basic-scatter.html')
如果我隨后向 DataFrame 添加一個包含 1991-1997 年值的測試國家/地區,則不需要更改其余代碼,氣泡圖將相應更新。
# I added a test country with datadf = pd.DataFrame({1991:[10,100,50,10], 1992:[14,30,22,20], 1993:[16,70,30,30], 1994:[18,85,65,40], 1995:[20,30,70,50], 1996:[42,42,66,60], 1997:[64,64,60,70]}) df.index = ['US','JAPAN','CN','TEST'] colors = ['rgb(150,204,90)','rgb(255, 130, 71)','rgb(255, 193, 37)','rgb(100, 100, 100)']

TA貢獻1794條經驗 獲得超8個贊
代碼已更新到版本 2,可以從 .xlsx 文件讀取數據并繪制氣泡圖。與之前的數據相比,名為“grape output.xlsx”的原始數據添加了新項目:
1991 1992 1993 1994 1995 1996 1997 1998 1999
US 10 14 16 18 20 42 64 100 50
JAPAN 100 30 70 85 30 42 64 98 24
CN 50 22 30 65 70 66 60 45 45
INDIA 90 88 35 50 90 60 40 66 76
UK 40 50 70 50 25 30 22 40 60
這是代碼:
# Version 2
import plotly as py
import plotly.graph_objs as go
import openpyxl
import pandas as pd
wb = openpyxl.load_workbook('grape output.xlsx')
sheet = wb['Sheet1']
row_max = sheet.max_row
col_max = sheet.max_column
first_row_list = []
first_col_list = []
for col_n in range(2, col_max+1):
first_row_list.append(sheet.cell(row=1, column=col_n).value)
for row_n in range(2,row_max+1):
first_col_list.append(sheet.cell(row=row_n, column=1).value)
data_all = pd.read_excel('grape output.xlsx')
data = data_all.loc[:,first_row_list]
df = pd.DataFrame(data)
df.index = first_col_list
colors = ['rgb(150,204,90)','rgb(255, 130, 71)','rgb(255, 193, 37)','rgb(180,240,190)','rgb(255, 10, 1)',
'rgb(25, 19, 3)','rgb(100, 100, 100)','rgb(45,24,200)','rgb(33, 58, 108)','rgb(35, 208, 232)']
data = [go.Scatter(
x=df.columns,
y=[country]*len(df.columns),
mode='markers+text',
marker=dict(
color=colors[num],
size= df.loc[country],
showscale = False,
),
text=list(map(str, df.loc[country])),
textposition='middle center',
)
for num, country in enumerate(reversed(df.index))
]
layout = go.Layout(plot_bgcolor='rgb(10, 10, 10)',
paper_bgcolor='rgb(20, 55, 100)',
font={
'size': 15,
'family': 'sans-serif',
'color': 'rgb(255, 255, 255)'
},
width=1000,
height=800,
xaxis=dict(title='Output of grapes per year in US, JAPAN and CN'),
showlegend=False,
margin=dict(l=100, r=100, t=100, b=100),
hovermode = False,
)
fig = go.Figure(data=data, layout=layout)
py.offline.plot(fig, filename='basic-scatter.html')
現在結果是這樣的:
還有一些小問題:
如何去掉 1990 和 2000 這兩個數字以及 1990 和 2000 的白色垂直線?
如何為1991、1993、1995、1997、1999畫白線并以橫坐標軸顯示所有這些年份?
請更正代碼 Versinon 2 以改進它。謝謝你!
添加回答
舉報