python - 单击条形图中的条形可生成该条形图中值的散点图

标签 python matplotlib plotly plotly-dash plotly-python

此代码生成条形图:

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()

输出为:

enter image description here

我想单击任何红色条,它会将我带到该类中值的散点图。

我可以用这个生成散点图:

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()

enter image description here

而且我知道如何通常单击一个栏来返回一个数据框,我可以将其放入散点图中,如下所示:

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

我猜这是因为第一个图使分组条形图生成一个图形,而直方图示例生成两个图?有人可以告诉我哪里出错了吗?

最佳答案

您没有指定您希望以任何方式组合plotly和matplotlib,所以如果您想知道如何使用Plotly准确地完成您所要求的操作,这里有一个设置。如果您可以使用它,我很乐意解释详细信息。

Plotly Dash 应用程序

enter image description here

完整代码:

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)

关于python - 单击条形图中的条形可生成该条形图中值的散点图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69832069/

相关文章:

python libusb1 : asynchronous TRANSFER_NO_DEVICE status just after successful syncronous transfers

python - 努力从 cookiejar 对象中检索 csrf token

python - 使用 Libclang python 绑定(bind),如何检索添加到 C++ 类/结构中的注释?

python - 使用 %matplotlib 笔记本时图形被省略并缩进

c# - 是否可以在 C# Winforms WebBrowser 组件中使用 Plotly.js?

r - plotly::sublot 不显示两个标题

python - Python 元类与常规类继承有何不同?

python - 在 python 中使用 latex 进行字符串格式化时,字段名称中出现意外的 '{'

R Plot_ly : How to change colorbar color palette and colorthreshold values?

python - 从 Python 中的直方图中获取数据点