Display logos on Plot.ly Bar figure - python

I am currently doing a dataviz project, and I wish to add small images above each bar of my bar chart. For some reason, when I upload my own .png files, they can not be displayed.
When I use the .png files from the plot.ly documentation, it works fine. I produce it with the following:
new = go.Figure(data=[
go.Bar(name = 'DC Men',
x = dc_most_men.name,
y = dc_most_men.appearances,
marker_color ='rgb(244,188,60)'),
go.Bar(name = 'DC Females',
x = dc_most_females.name,
y = dc_most_females.appearances,
marker_color ='rgb(28,140,140)')
])
new.update_layout(
xaxis=dict(
showline=True,
showgrid=False,
showticklabels=True,
linecolor='rgb(204, 204, 204)',
linewidth=2,
ticks='outside',
tickfont=dict(
family='Arial',
size=12,
color='rgb(82, 82, 82)',
),
),
yaxis=dict(
showgrid=False,
zeroline=False,
showline=False,
showticklabels=True,
),
autosize=False,
margin=dict(
autoexpand=False,
l=100,
r=20,
t=110,
),
showlegend=False,
plot_bgcolor='white'
)
new.add_layout_image(
dict(
source='https://github.itu.dk/storage/user/2360/files/eeb40480-9c3b-11ea-99e6-b9ae4b500657',
x=0.07,
y=1,
))
new.add_layout_image(
dict(
source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/benzene.png",
x=0.17,
y=0.8,
))
new.add_layout_image(
dict(
source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/benzene.png",
x=0.275,
y=0.5,
))
new.update_layout_images(dict(
xref="paper",
yref="paper",
sizex=0.1,
sizey=0.1,
xanchor="right",
yanchor="bottom"
))
Which very nicely produces the following barchart:
However, when I upload my own files to GitHub, it seems to not display the logo at all. I made sure to change the path to the following link as well.
The link I use is: https://user-images.githubusercontent.com/47081217/82669721-3b97db00-9c3c-11ea-90f6-c525e647bc49.png
Is there anything I have over-looked?

I don't think that from github could open an external link. Have you tried to download the png on the same folder where your notebook/script is?

I thought that if the format on GitHub is not the normal format, maybe the PILLOW library can handle it.
from PIL import Image
img = Image.open('https://github.itu.dk/storage/user/2360/files/eeb40480-9c3b-11ea-99e6-b9ae4b500657')

Related

Add vrect with text to plotly express with button

I have the following code for a vertical rectangle in plotly express:
fig.add_vrect(
x0 = '2020-04',
x1 = '2020-09',
fillcolor="red",
opacity=0.25
)
I would like to make a button where the user can toggle with rectangle on and off, and when it's on there's some text in the middle. I would like them to be off by default.
You can use dictionaries to create your rectangle shape and rectangle annotation and then use these as arguments for a button. A few details: we use the "relayout" method for buttons because toggling a shape and text annotation means we are only changing the layout, and args and args2 tells the button how to behave when toggled on/off.
Edit: in order to keep another shape (like a vline) on the figure, you can add the vline to both args and args2 of your button so the vline remains when the button is toggled
import plotly.express as px
fig = px.scatter(
x=['2020-01-30', '2020-04-01', '2020-04-01','2020-09-01'],
y=[3,2,3,2]
)
fig.add_vline(
x='2020-02',
line_dash='dash'
)
vline_shape = [dict(
type='line',
x0='2020-02',
x1='2020-02',
xref='x',
y0=0,
y1=1,
yref='y domain',
line= {'dash': 'dash'}
)]
rectangle_shape = [dict(
type='rect',
x0='2020-04',
x1='2020-09',
xref='x',
y0=0,
y1=1,
yref='y domain',
fillcolor='red',
opacity=0.25
)]
rectangle_annotation = [dict(
showarrow=False,
x='2020-06-15',
y=2.5,
text="Selected Time Period"
)]
fig.update_layout(
updatemenus=[
dict(
type="buttons",
buttons=[
dict(label="Toggle Rectangle",
method="relayout",
args=[{
"shapes": rectangle_shape + vline_shape,
"annotations": rectangle_annotation}],
args2=[{
"shapes": vline_shape,
"annotations": []}]),
# dict(label="Untoggle Rectangle",
# method="relayout",
# args=["shapes", []]),
],
)
]
)
fig.show()

Dash+Plotly Synchronize zoom and pan between two plots using imshow

I try to synchronize zoom and pan between two graphs in a dashboard (dash + plotly). I obtain strange behavior when I zoom on a graph, the second graph does not update. I need to zoom on the second graph to make both graphs update but not with the same zoom nor the same location on the graphs. Furthermore the shapes of the two graphs change.
Below is the code I am in. I do not see I am doing wrong.
import os
from dash import Dash, html, dcc, Input, Output, State
import plotly.express as px
import numpy as np
import rasterio as rio
app2 = Dash(__name__)
data_folder = r'.\data'
store = {}
for filename in os.listdir(data_folder):
if os.path.isfile(os.path.join(data_folder, filename)):
band_name = filename.replace('.', '_').split(sep='_')[-2]
with rio.open(os.path.join(data_folder, filename)) as dataset:
nb_band = dataset.count
if nb_band == 1:
data = dataset.read(1)
else:
data = dataset.read(tuple(range(1, nb_band + 1)))
if band_name == 'triband':
data = np.swapaxes(data, 2, 0)
data = np.swapaxes(data, 0, 1)
store[band_name] = data.astype(float)
else:
store[f'B{band_name}'] = data.astype(float)
fig1 = px.imshow(store['triband'])
fig1.update_xaxes(showticklabels=False, showgrid=False, zeroline=False)
fig1.update_yaxes(showticklabels=False, showgrid=False, zeroline=False)
fig1.update_layout(
margin=dict(l=0, r=0, t=0, b=0),
plot_bgcolor='rgba(0, 0, 0, 0)',
paper_bgcolor='rgba(0, 0, 0, 0)',
)
# Application structure and content
app2.layout = html.Div(className='main', children=[
html.H1(children='Hello Dash', style={'padding': 10}),
html.Div(children=[
html.Div(children=[
dcc.Graph(
id='graph1',
figure=fig1,
responsive=True
)
], style={'padding': 5, 'flex': 1}),
html.Div(children=[
dcc.Graph(
id='graph2',
figure=fig1,
responsive=True
)
], style={'padding': 5, 'flex': 1})
], style={'display': 'flex', 'flex-direction': 'row'}),
])
#app2.callback(Output('graph2', 'figure'),
Input('graph1', 'relayoutData'),
State('graph2', 'figure'))
def graph_event1(select_data, fig):
if select_data is not None:
try:
fig['layout']['xaxis']['range'] = [select_data['xaxis.range[0]'], select_data['xaxis.range[1]']],
fig['layout']['yaxis']['range'] = [select_data['yaxis.range[0]'], select_data['yaxis.range[1]']]
except KeyError:
pass
return fig
#app2.callback(Output('graph1', 'figure'),
Input('graph2', 'relayoutData'),
State('graph1', 'figure'))
def graph_event2(select_data, fig):
if select_data is not None:
try:
fig['layout']['xaxis']['range'] = [select_data['xaxis.range[0]'], select_data['xaxis.range[1]']],
fig['layout']['yaxis']['range'] = [select_data['yaxis.range[0]'], select_data['yaxis.range[1]']]
except KeyError:
pass
return fig
if __name__ == '__main__':
app2.run_server(debug=True)
I found a solution : rather than creating two graphs, I created a graph with several subplots and force zoom and pan between subplots.
fig = make_subplots(rows=1, cols=3, shared_xaxes=True, shared_yaxes=True)
fig.add_trace(
px.imshow(store['triband']).data[0],
row=1, col=1
)
fig.add_trace(
px.imshow(index_store['NDVI']).data[0],
row=1, col=2
)
fig.add_trace(
px.imshow(np.where(index_store['NDVI'] >= np.median(index_store['NDVI']),
0.8 * np.max(index_store['NDVI']),
0.8 * np.min(index_store['NDVI']))
).data[0],
row=1, col=3
)
fig.update_xaxes(matches='x', showticklabels=False, showgrid=False, zeroline=False)
fig.update_yaxes(matches='y', showticklabels=False, showgrid=False, zeroline=False)

Dash-Plolty does not show images on the figure

I am trying to put images on my figure, like a watermark, I am following the documentation. and it works with the 'Vox' example. However, when I try to put local images to the figure they do not show up.
Here is my code:
import plotly.express as px
import requests
import pandas as pd
response = requests.get("https://api.covalenthq.com/v1/1/address/0x343A53A1E8b17beDd15F47a28195Bc8C120d4443/portfolio_v2/?format=format%3Dcsv&key=ckey_57eeb470248541708eeaf028c9d").json()['items']
data=pd.json_normalize(response,record_path=['holdings'],meta=['contract_ticker_symbol','contract_name',"contract_address"])
data['timestamp']=pd.to_datetime(data['timestamp']).dt.strftime('%D')
#colors = {
# 'background': 'black', #Sets plot background color black
# 'text': '#FFFFFF' #Sets plot text color white
#}
fig = px.line(data, x="timestamp", y="close.quote", color="contract_name",color_discrete_sequence=["#ff4c8b", "#00d8d5",'#f7f7f7'], line_group="contract_ticker_symbol",labels={ #Changes colum names
"contract_name":'Contract Name',
"timestamp": "Date",
"close.quote": "USD Value",
"contract_ticker_symbol": "Ticker"
}, title='Asset Value Over Time', hover_name="contract_ticker_symbol")
fig.add_layout_image(
dict(
source="vox.png",
xref="paper", yref="paper",
x=0.5, y=0.24,
sizex=0.5, sizey=0.6,
xanchor="center", yanchor="bottom"
)
)
fig.add_layout_image(
dict(
source="aa_footer.svg",
xref="paper", yref="paper",
x=0.7, y=(-0.20),
sizex=1.7, sizey=.8,
xanchor="center", yanchor="bottom"
)
)
fig.update_layout(plot_bgcolor='black', paper_bgcolor='black',font_color='#FFFFFF')
# update layout properties
fig.update_layout(
margin=dict(r=20, l=300, b=75, t=125),
title=("Asset Valuation Overtime<br>" +
"<i>Assets in Ethereum Blockchain</i>"),
)
fig.update_xaxes(showgrid=False) #hide vertical gridlines
fig.show()
I tried with both putting my images into 'assets' folder and outside as well as uploading them to imgBB. still no response
This is the figure I am getting:
[![enter image description here][2]][2]
Can somebody please tell me how to fix this problem
The easiest way to do this is to specify the data obtained by using the PILLOW library as the source. The official reference description can be found here.
from PIL import Image # new import
img = Image.open('./data/vox.png') # image path
# defined to source
fig.add_layout_image(
dict(
source=img,
xref="paper", yref="paper",
x=0.5, y=0.24,
sizex=0.5, sizey=0.6,
xanchor="center",
yanchor="bottom",
opacity=0.5
)
)

Plotly legend next to each subplot, Python

After noticing that there was no answer to this question at the moment, I would like to know if anyone has an idea how to:
Have a legends for each subplot.
Group legends by name. (Ex: for different subplots, all have the same two curves but with different values).
Here's my Plotly script:
from plotly import tools
import plotly.plotly as py
import plotly.graph_objs as go
import plotly
nom_plot=[]
trace1 = go.Scatter(x=[1, 2, 3], y=[4, 5, 6],name='1',showlegend=True)
nom_plot.append('GRAPH 1')
trace2 = go.Scatter(x=[20, 30, 40], y=[50, 60, 70],name='2',yaxis='y2')
nom_plot.append('GRAPH 2')
trace3 = go.Scatter(x=[300, 400, 500], y=[600, 700, 800],showlegend=False)
nom_plot.append('GRAPH 3')
trace4 = go.Scatter(x=[4000, 5000, 6000], y=[7000, 8000, 9000])
nom_plot.append('GRAPH 4')
trace5 = go.Scatter(x=[20, 30, 40], y=[50, 60, 70])
nom_plot.append('GRAPH 5')
print(trace1)
fig = tools.make_subplots(rows=4, cols=2, subplot_titles=(nom_plot))
fig.append_trace(trace1, 1, 1)
fig['layout']['xaxis1'].update(title='xaxis 1 title')
fig.append_trace(trace2, 1, 1)
fig.append_trace(trace3, 2, 1)
fig.append_trace(trace4, 2, 2)
fig['layout']['yaxis3'].update(title='yaxis 3 title')
fig.append_trace(trace5, 3, 1)
fig['layout']['yaxis2'].update(
overlaying='y1',
side='right',
anchor='x1',
# domain=[0.15, 1],
range=[2, 6],
# zeroline=False,
showline=True,
showgrid=False,
title='yaxis 3 title'
)
fig['layout'].update(height=1000, width=1000, title='Multiple Subplots' +' with Titles')
plotly.offline.plot(fig, filename='multiple-y-subplots6.html')
This what I obtain (Using Plotly Script above):
And this is what I want (Made by Pygal):
The solution is to create an HTML file that merge sevral charts offline rendered as html files:
import plotly
import plotly.offline as py
import plotly.graph_objs as go
fichier_html_graphs=open("DASHBOARD.html",'w')
fichier_html_graphs.write("<html><head></head><body>"+"\n")
i=0
while 1:
if i<=40:
i=i+1
#______________________________--Plotly--______________________________________
color1 = '#00bfff'
color2 = '#ff4000'
trace1 = go.Bar(
x = ['2017-09-25','2017-09-26','2017-09-27','2017-09-28','2017-09-29','2017-09-30','2017-10-01'],
y = [25,100,20,7,38,170,200],
name='Debit',
marker=dict(
color=color1
)
)
trace2 = go.Scatter(
x=['2017-09-25','2017-09-26','2017-09-27','2017-09-28','2017-09-29','2017-09-30','2017-10-01'],
y = [3,50,20,7,38,60,100],
name='Taux',
yaxis='y2'
)
data = [trace1, trace2]
layout = go.Layout(
title= ('Chart Number: '+str(i)),
titlefont=dict(
family='Courier New, monospace',
size=15,
color='#7f7f7f'
),
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(0,0,0,0)',
yaxis=dict(
title='Bandwidth Mbit/s',
titlefont=dict(
color=color1
),
tickfont=dict(
color=color1
)
),
yaxis2=dict(
title='Ratio %',
overlaying='y',
side='right',
titlefont=dict(
color=color2
),
tickfont=dict(
color=color2
)
)
)
fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename='Chart_'+str(i)+'.html',auto_open=False)
fichier_html_graphs.write(" <object data=\""+'Chart_'+str(i)+'.html'+"\" width=\"650\" height=\"500\"></object>"+"\n")
else:
break
fichier_html_graphs.write("</body></html>")
print("CHECK YOUR DASHBOARD.html In the current directory")
Result:
I used two side by side Div elements to emulate Plotly subplot. Doing this way, we have independent legends. However, if we want to share an axis, we should do it manually:
app.layout = html.Div(children=[
html.Div(['YOUR FIRST GRAPH OBJECT'],
style = {'float':'left', 'width':'49%'}) ,
html.Div(['YOUR SECOND GRAPH OBJECT'],
style = {'float':'right', 'width':'49%'})
])

Plotly Python - Change font of table

I have a table that I produced in plotly, and I want to change the font to 'Gill Sans'.
I am having trouble making it change. Is this possible?
This is my code:
groupA = new_df.groupby('Call').agg({'TotalGrantValue':sum, 'FirstReceivedDate':'count'}).rename(columns={'FirstReceivedDate':'Count'})
groupA['TotalGrantValue'] = groupA['TotalGrantValue'].map('{:,.2f}'.format)
colorscale = [[0, '#7f7f7f'],[.5, '#F1EDED'],[1, '#ffffff']]
table = ff.create_table(groupA, index=True,colorscale=colorscale, height_constant=14, index_title='Date')
table.layout.width = 700
for i in range(len(table.layout.annotations)):
table.layout.annotations[i].font.size = 10
plotly.offline.iplot(table, config={"displayModeBar": False}, show_link=False, filename='index_table_pd')
You need to define a layout parameter as stated in https://plot.ly/python/axes/.
from the same page, there is an example code that should help you:
layout = go.Layout(
xaxis=dict(
title='AXIS TITLE',
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'
),
showticklabels=True,
tickangle=45,
tickfont=dict(
family='Old Standard TT, serif',
size=14,
color='black'
),
exponentformat='e',
showexponent='All'
),
yaxis=dict(
title='AXIS TITLE',
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'
),
showticklabels=True,
tickangle=45,
tickfont=dict(
family='Old Standard TT, serif',
size=14,
color='black'
),
exponentformat='e',
showexponent='All'
)
)
fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='axes-labels')

Categories