I am trying to create a 3D plot with plotly. In the plotting area, I want a grid of floating text annotations. This is my MWE:
import plotly.graph_objs as go
import dash
from dash import html, dcc, Input, Output
import random
import itertools
def generate_figure(data):
text_positions = [[[-1,-1,0], [-1,1,0]], [[1,-1,0], [1,1,0]]]
fig = go.Figure()
fig.add_trace(go.Scatter3d(
x=[v[0] for rows in text_positions for v in rows],
y=[v[1] for rows in text_positions for v in rows],
z=[v[2] for rows in text_positions for v in rows],
text=[f"{f'{data['row'][row]}' if data['row'][row] is not None else 'N/A'} x {f'{data['col'][col]}' if data['col'][col] is not None else 'N/A'}" for row, rows in enumerate(text_positions) for col, _ in enumerate(rows)],
mode='text',
textposition="middle center",
textfont=dict(size=12, color='black'),
))
fig.update_layout(
scene=dict(
xaxis=dict(range=[-2, 2]),
yaxis=dict(range=[-2, 2]),
zaxis=dict(range=[-1, 1])
)
)
return fig
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='graph'),
html.Button('Refresh data', id='btn')
])
@app.callback(
Output('graph', 'figure'),
Input('btn', 'n_clicks')
)
def update_graph(n_clicks):
data = [0,1,2,3]
col = list(random.choice(list(itertools.combinations(data, 2))))
row = [item for item in data if item not in col]
return generate_figure({'col': col, 'row': row})
if __name__ == '__main__':
app.run(debug=True)
I've added a button to randomize the order of the numbers. The plot updates as expected, but the font size of some of the annotations gets smaller. Obviously, this is not what I want.
I've already tried to use different traces for every annotation, which didn't work. In addition, I've tried to use different text formats, but that didn't help either.
Any help would be very much appreciated.
