此代碼生成條形圖:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import plotly.graph_objects as go
classes= ['class1', 'class2', 'class3', 'class4', 'class5', 'class6', 'class7']
lens = [199, 30, 89, 59, 109, 115, 89]
nums = [145, 457, 123, 67, 35, 31, 134]
fig = go.Figure(data=[
go.Bar(name='Length', x=classes, y=lens),
go.Bar(name='Number', x=classes, y=nums),
])
# Change the bar mode
fig.update_layout(barmode='group')
fig.update_layout(title_text='Length and Number',
title_x=0.1,
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
bargap=0.30,
bargroupgap=0.0,
margin=dict(l=50, r=50, t=50, b=50),
xaxis_title="Score Class",
yaxis_title="Length and Number",
yaxis = dict(
tickfont = dict(size=13)),
xaxis = dict(
tickfont = dict(size=13)),)
fig.update_xaxes(showline=True, linewidth=2, linecolor='black')
fig.update_yaxes(showline=True, linewidth=2, linecolor='black')
fig.show()
輸出是:

我想單擊任何紅色條,它會將我帶到該類中的值的散點圖。
我可以用這個生成散點圖:
dict2 = {}
dict2['class1'] = [(2,2),(1,1),(2,3),(3,4),(5,1)]
dict2['class2'] = [(3,1),(4,4),(5,5),(6,2),(7,1)]
dict2['class3'] = [(3,2),(4,1),(5,4),(6,4),(7,1)]
dict2['class4'] = [(3,1),(4,5),(6,3),(4,3),(5,3)]
dict2['class5'] = [(1,1),(1,1),(1,2),(3,1),(4,3)]
dict2['class6'] = [(2,2),(2,1),(2,3),(5,3),(6,4)]
class1_dict = {}
class1_dict['xs'] = [i[0] for i in dict2['class1']]
class1_dict['ys'] = [i[1] for i in dict2['class1']]
plt.scatter(class1_dict['xs'],class1_dict['ys'])
plt.show()

而且我知道通常如何單擊一個條形以回傳一個資料框,我可以像這樣將其放入散點圖中:
dict_name = {}
dict_name['classes'] = classes
dict_name['lens'] = lens
dict_name['nums'] = nums
df = pd.DataFrame.from_dict(dict_name, orient='columns')
print(df)
axs = df.hist(bins=4, picker=True)
ax = axs[0, 0]
def onpick(event):
bar = event.artist
left = bar.get_x()
right = left bar.get_width()
col_df = df[(df.lens >= left) & (df.lens <= right)]
ax.figure.canvas.mpl_connect('pick_event', onpick)
#plt.show()
我正在嘗試更改最后一段代碼,因此axs = df.hist(bins=4, picker=True)我可以在條形圖中讀取而不是,并在單擊時回傳一個我可以讀取到散點圖中的資料框。
所以我想我只需要以某種方式添加這兩行:
axs = df.hist(bins=4, picker=True)
ax = axs[0, 0]
到我的條形圖代碼,使其可點擊。
所以我想因為axs這只是一個情節,就是這樣fig,我可以將此行添加到條形圖代碼中,它會起作用:
fig = go.Figure(data=[
go.Bar(name='Length', x=classes, y=lens),
go.Bar(name='Number', x=classes, y=nums),
])
ax = fig[0,0]
我得到的錯誤是:
Traceback (most recent call last):
File "/Users/slowatkela/anaconda/lib/python3.7/site-packages/plotly/basedatatypes.py", line 188, in _check_path_in_prop_tree
obj = obj[p]
File "/Users/slowatkela/anaconda/lib/python3.7/site-packages/plotly/basedatatypes.py", line 732, in __getitem__
prop = BaseFigure._str_to_dict_path(prop)
File "/Users/slowatkela/anaconda/lib/python3.7/site-packages/plotly/basedatatypes.py", line 1839, in _str_to_dict_path
ret = _str_to_dict_path_full(key_path_str)[0]
File "/Users/slowatkela/anaconda/lib/python3.7/site-packages/plotly/basedatatypes.py", line 71, in _str_to_dict_path_full
if len(key_path_str):
TypeError: object of type 'int' has no len()
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test3.py", line 17, in <module>
ax=axs[0,0]
File "/Users/slowatkela/anaconda/lib/python3.7/site-packages/plotly/basedatatypes.py", line 754, in __getitem__
err = _check_path_in_prop_tree(self, orig_prop, error_cast=PlotlyKeyError)
File "/Users/slowatkela/anaconda/lib/python3.7/site-packages/plotly/basedatatypes.py", line 212, in _check_path_in_prop_tree
if prop[i][0] == "_":
TypeError: 'int' object is not subscriptable
I guess it's because the first plot makes a grouped bar plot makes one figure whereas the histogram example makes two plots? Could someone show me where I'm going wrong?
uj5u.com熱心網友回復:
您沒有指定要以任何方式組合 plotly 和 matplotlib,因此,如果您想知道如何使用 Plotly 準確執行您要求的操作,這里有一個設定。如果這是你可以使用的東西,我很樂意解釋細節。
Plotly Dash 應用程式

完整代碼:
import plotly.graph_objects as go # or plotly.express as px
fig = go.Figure()
from jupyter_dash import JupyterDash
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import json
import plotly.express as px
styles = {
'pre': {
'border': 'thin lightgrey solid',
'overflowX': 'scroll'
}
}
df = px.data.tips()
fig1 = px.bar(df, x="sex", y="total_bill", color='time')
fig2= px.scatter(df, x="total_bill", y="tip")
# f = fig.full_figure_for_development(warn=False)
app = JupyterDash(__name__)
app.layout = html.Div([
dcc.Graph(id = 'fig1', figure=fig1),
dcc.Graph(id = 'fig2', figure=fig2),
html.Div(className='row', children=[
html.Div([
dcc.Markdown(("""
Clickinfo:
""")),
html.Pre(id='txt_output', style=styles['pre']),
], className='three columns'),
])
])
# inspect clickdata
@app.callback(
Output('txt_output', 'children'),
[Input('fig1', 'clickData')])
def display_click_data(clickData):
if clickData is not None:
output = json.dumps({'clickinfo':clickData}
, indent = 2)
return output
# Use clickrInfo from fig1 to subset data in fig2
@app.callback(
Output('fig2', 'figure'),
[Input('fig1', 'clickData')])
def display_click_data(clickData):
if clickData is not None:
subset = clickData['points'][0]['x']
fig = px.scatter(df[df['sex'] == subset], x="total_bill", y="tip")
return fig
return fig2
app.run_server(mode='external', port = 8071, dev_tools_ui=True,
dev_tools_hot_reload =True, threaded=True)
uj5u.com熱心網友回復:
正如在評論中提到的@JohanC,plotly并matplotlib有很大的不同庫。這意味著它們的物件不與任何型別的類層次結構相關,并且不共享相同的屬性。
因此,您不能將 matplotlibaxes物件設定為與plotly圖形物件相等。繪圖圖形物件與 matplotlib 圖形物件不同。您可能需要留在一個庫中才能實作您想要的。如果 matplotlibonpick功能對您很重要,那么您可能應該留在 matplotlib 中。我相信在 matplotlib 中你可以構建,hoverevents但它比在 plotly 中更努力,后者將hoverevents幾乎所有數字作為默認值。
此外,情節圖不是陣列,因此fig[0,0]沒有意義。也許您打算訪問fig.datawhich 是一個元組,這意味著您可以訪問fig.data[0], fig.data[1], ... fig.data[N]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/350084.html
