Adding caption below Python Plotly Choropleth Map - python

I want to add a caption below my plotly choropleth Map (using Python). I've looked into using annotations with graph_objs, but it only seems to work for locations within the map area. Is there a way to make the annotations show up below the choropleth map and/or is there an alternative way of doing this?
Right now I'm getting this but would like the caption to appear below the map area:
I've tried inputting y values less than 0, but then the text annotations just don't show up at all.
Here's my code:
import plotly.graph_objects as go
import pandas as pd
import plotly
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv')
fig = go.Figure(data=go.Choropleth(
locations = df['CODE'],
z = df['GDP (BILLIONS)'],
text = df['COUNTRY'],
colorscale = 'Blues',
autocolorscale=False,
reversescale=True,
marker_line_color='darkgray',
marker_line_width=0.5,
colorbar_tickprefix = '$',
colorbar_title = 'GDP<br>Billions US$',
))
fig.update_layout(
title_text='2014 Global GDP',
geo=dict(
showframe=False,
showcoastlines=False,
projection_type='equirectangular'
),
annotations = [dict(
x=0.5,
y=0, #Trying a negative number makes the caption disappear - I'd like the caption to be below the map
xref='paper',
yref='paper',
text='Source: <a href="https://www.cia.gov/library/publications/the-world-factbook/fields/2195.html">\
CIA World Factbook</a>',
showarrow = False
)]
)
fig.show()

Setting y=-0.1 works fine on my end:
Plot 1
If that for some reason is not the case on your end (perhaps a version issue?), you should try to just leave it at y=0 and rather make room below the figure utself by adjustin the margins of the plot like this:
fig.update_layout(
margin=dict(l=20, r=20, t=60, b=20),
paper_bgcolor="LightSteelBlue")
Plot 2:
Complete code:
import plotly.graph_objects as go
import pandas as pd
import plotly
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv')
fig = go.Figure(data=go.Choropleth(
locations = df['CODE'],
z = df['GDP (BILLIONS)'],
text = df['COUNTRY'],
colorscale = 'Blues',
autocolorscale=False,
reversescale=True,
marker_line_color='darkgray',
marker_line_width=0.5,
colorbar_tickprefix = '$',
colorbar_title = 'GDP<br>Billions US$',
))
fig.update_layout(
title_text='2014 Global GDP',
geo=dict(
showframe=False,
showcoastlines=False,
projection_type='equirectangular'
),
annotations = [dict(
x=0.5,
y=0, #Trying a negative number makes the caption disappear - I'd like the caption to be below the map
xref='paper',
yref='paper',
text='Source: <a href="https://www.cia.gov/library/publications/the-world-factbook/fields/2195.html">\
CIA World Factbook</a>',
showarrow = False
)]
)
fig.update_layout(
margin=dict(l=20, r=20, t=60, b=20),
paper_bgcolor="LightSteelBlue")
fig.show()

Related

Add two texts to each bar chart in plotly

I am working on plotly (python) to plot a horizontal bar chart like the below figure.
import plotly.express as px
fig = px.bar(
x=prices,
y=['Average $' + str(round(avg_price, 2)), 'Lowest $' +
str(round(min_price, 2)), 'Last $' + str(round(last_price, 2)),
'Proposed $' + str(round(proposed_price, 2))],
color=['Last', 'Average', 'Lowest', 'Proposed'],
text=delta,
orientation='h',
height=400,
)
fig.add_vline(x=spend[-1], line_width=2, line_dash="dash",
line_color="red")
fig.add_vline(x=max(spend), line_width=2, line_dash="dash",
line_color="green")
fig.update_traces( textposition='outside')
fig.update_layout(
title="Saving/Loss diagram",
xaxis_title="",
yaxis_title="",
legend_title="Vendor names",
width=1000,
)
fig.show()
In this figure I display text only outside of each bar chart. But now I am going to display another text inside each bar chart. How can I do that in plotly (python)?
If you want to add a text inside the bars with plotly.express, you could use fig.update_traces with two parameters texttemplate and textposition
You could try this code:
import plotly.express as px
data_canada = px.data.gapminder().query("country == 'Canada'")
fig = px.bar(data_canada, x='year', y='pop')
fig.update_traces(texttemplate = data_canada.year.unique(),textposition = "inside")
fig.show()
There is an option to do all this with plotly.graph_objects.
But here, you should add text that appears inside the bars and textposition adjust the text.
import plotly.graph_objects as go
data_canada = px.data.gapminder().query("country == 'Canada'")
fig = go.Figure(data=[go.Bar(
x=data_canada.year, y=data_canada["pop"],
text=data_canada.year.unique(),
textposition='inside'
)])
fig.show()
Update based on the comments:
You can change the position of each text for each bar but the possible positions are four positions: "inside" | "outside" | "auto" | "none" as documented on the main page of plotly here, search for textposition attribute.
To do this you can do it as follows:
import plotly.express as px
x = ['Aaron', 'Bob', 'Chris','Tom','Anna']
y = [5, 10, 6, 11, 8]
texts = ["first","second","third","fourth","fifth"]
positions = ['inside','outside','auto','outside','inside']
fig = px.bar(x=x, y=y)
fig.update_traces(texttemplate = texts, textposition = positions)
fig.show()

plotly: How to add text to existing figure?

Is it possible to add some text on the same html file as my plotly graph?
For example :
This is the code that generates a graph :
data = pd.read_csv('file.csv')
data.columns = ['price', 'place', 'date']
fig = px.scatter(data, x = "place", y = "price", )
fig.write_html("done.html")
This graph will generate a pyplot graph in an html file and I want to add some simple text (such as a conclusion line explaning the graph) under the graph.
This is an example of the output I would like:
ly
You can use fig.update_layout(margin=dict()) to make room for an explanation, and then fig.add_annotation() to insert any text you'd like below the figure utself to get this:
Complete code:
import plotly.graph_objects as go
import numpy as np
x = np.arange(-4,5)
y=x**3
yticks=list(range(y.min(), y.max(), 14))
#yticks.append(y.max())9
# build figure
fig = go.Figure(data=go.Scatter(x=x, y=y))
# make space for explanation / annotation
fig.update_layout(margin=dict(l=20, r=20, t=20, b=60),paper_bgcolor="LightSteelBlue")
# add annotation
fig.add_annotation(dict(font=dict(color='yellow',size=15),
x=0,
y=-0.12,
showarrow=False,
text="A very clear explanation",
textangle=0,
xanchor='left',
xref="paper",
yref="paper"))
fig.show()

Seaborn/Plotly multiple y-axes

I would like to get a plot with more than two different y-axes in seaborn using a pandas dataframe similar to this example for matlotlib: https://matplotlib.org/examples/axes_grid/demo_parasite_axes2.html
As it will be used in a function I want to be flexible in selecting how many and which column of a Pandas dataframe will be ploted.
Unfortunately Seaborn seems to only move the last added scale.
Here is what I want to do with a Seaborn sample dataset:
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
import seaborn as sns
df=sns.load_dataset("mpg")
df=df.loc[df['model_year']<78]
show=['mpg','displacement','acceleration']
sns.set(rc={'figure.figsize':(11.7,8.27)})
sns.scatterplot('weight',show[0],data=df.reset_index(),style='model_year')
del show[0]
k=1
off=0
for i in show:
a = plt.twinx()
a=sns.scatterplot('weight',i,data=df.reset_index(),ax=a, color=list(mcolors.TABLEAU_COLORS)[k],legend=False,style='model_year')
a.spines['right'].set_position(('outward', off))
a.yaxis.label.set_color(list(mcolors.TABLEAU_COLORS)[k])
k+=1
off+=60
I want to create a function with the possibility to flexible plot different columns. Up to now this seems to be quite complicated in plotly to me (no way of just do a loop). I would also go with plotly, if there is a good way.
There is actually a good way in Plotly, you can see the code example for the picture below, similar to your matplotlib example in this section of the docs.
I now implemented this using plotly.
import seaborn as sns
import plotly.graph_objects as go
df=sns.load_dataset("mpg")
show=['mpg','displacement','acceleration']
mcolors=[
'#1f77b4', # muted blue
'#ff7f0e', # safety orange
'#2ca02c', # cooked asparagus green
'#d62728', # brick red
'#9467bd', # muted purple
'#8c564b', # chestnut brown
'#e377c2', # raspberry yogurt pink
'#7f7f7f', # middle gray
'#bcbd22', # curry yellow-green
'#17becf' # blue-teal
];
fig = go.Figure()
m=0
for k in df.model_year.unique():
fig.add_trace(go.Scatter(
x = df.loc[df.model_year == k]['weight'],
y = df.loc[df.model_year == k][show[0]],
name = str(k),
mode = 'markers',
marker_symbol=m,
marker_line_width=0,
marker_size=6,
marker_color=mcolors[0],
))
m+=1
layout = {'xaxis':dict(
domain=[0,0.7]
),
'yaxis':dict(
title=show[0],
titlefont=dict(
color=mcolors[0]
),
tickfont=dict(
color=mcolors[0]
),
showgrid=False
)}
n=2
for i in show[1::]:
m=0
for k in df.model_year.unique():
fig.add_trace(go.Scatter(
x = df.loc[df.model_year == k]['weight'],
y = df.loc[df.model_year == k][i],
name = str(k),
yaxis ='y'+str(n),
mode = 'markers',
marker_symbol=m,
marker_line_width=0,
marker_size=6,
marker_color=mcolors[n],
showlegend = False
))
m+=1
layout['yaxis'+str(n)] = dict(
title=i,
titlefont=dict(
color=mcolors[n]
),
tickfont=dict(
color=mcolors[n]
),
anchor="free",
overlaying="y",
side="right",
position=(n)*0.08+0.55,
showgrid=False,
)
n+=1
fig.update_layout(**layout)
fig.show()

Adding a secondary axis in Plotly Python

I'm working with a Dash graph object and I'm fairly new to it. I'm attempting to pass in a graph that has 2 scatter charts and a bar chart on the same figure but I'd like the bar chart (green) to be on it's own secondary y axis so it looks better than it does here:
Now from what I understand about Dash, I have to pass a go.Figure() object so I have a function which defines the data and the layout. I saw in the plotly documentation that you can use plotly express add secondary axis but I'm not sure how to do that within my frame work here. Any help would be greatly appreciated!
Here's my code:
def update_running_graph(n_intervals):
df = pd.read_csv(filename)
trace1 = go.Scatter(x=df['Timestamp'],
y=df['CLE'],
name='Crude',
mode='lines+markers')
trace2 = go.Scatter(x=df['Timestamp'],
y=df['y_pred'],
name='Model',
mode='lines+markers')
trace3 = go.Bar(x=df['Timestamp'],
y=df['ModelDiff'],
name='Diff',
)
data = [trace1, trace2,trace3]
layout = go.Layout(title='CLE vs Model')
return go.Figure(data=data, layout=layout)
To add a secondary y-axis in dash you could do the following:
def update_running_graph(n_intervals):
df = pd.read_csv(filename)
trace1 = go.Scatter(x=df['Timestamp'],
y=df['CLE'],
name='Crude',
mode='lines+markers',
yaxis='y1')
trace2 = go.Scatter(x=df['Timestamp'],
y=df['y_pred'],
name='Model',
mode='lines+markers',
yaxis='y1')
trace3 = go.Bar(x=df['Timestamp'],
y=df['ModelDiff'],
name='Diff',
yaxis='y2'
)
data = [trace1, trace2,trace3]
layout = go.Layout(title='CLE vs Model',
yaxis=dict(title='Crude and Model'),
yaxis2=dict(title='Moddel Difference',
overlaying='y',
side='right'))
return go.Figure(data=data, layout=layout)
you can add more y-axis they always need to have the form of yi with i the i-th axis. Then in the layout you can specify the layout of the i-th axis with yaxisi=dict(...).
This documentation page should be of use. Just modify to fit your code, since trace1 and trace2 appear to be on the same scale, just set trace3 to the secondary axis scale and you should be set. Below is an example with just only 2 but adding a third should not be too difficult.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])
# Add traces
fig.add_trace(
go.Scatter(x=[1, 2, 3], y=[40, 50, 60], name="yaxis data"),
secondary_y=False,
)
fig.add_trace(
go.Scatter(x=[2, 3, 4], y=[4, 5, 6], name="yaxis2 data"),
secondary_y=True,
)
# Add figure title
fig.update_layout(
title_text="Double Y Axis Example"
)
# Set x-axis title
fig.update_xaxes(title_text="xaxis title")
# Set y-axes titles
fig.update_yaxes(title_text="<b>primary</b> yaxis title", secondary_y=False)
fig.update_yaxes(title_text="<b>secondary</b> yaxis title", secondary_y=True)
fig.show()
Cheers!

How to change annotation orientation in plotly?

Say I have the following figure:
import numpy as np
import plotly.graph_objs as go
z=np.random.randint(1000, 11000, size=20)
trace=dict(type='scatter',
x=3+np.random.rand(20),
y=-2+3*np.random.rand(20),
mode='markers',
marker=dict(color= z,
colorscale='RdBu', size=14, colorbar=dict(thickness=20)))
axis_style=dict(zeroline=False, showline=True, mirror=True)
layout=dict(width=550, height=500,
xaxis=axis_style,
yaxis=axis_style,
hovermode='closest',
)
fig=go.FigureWidget(data=[trace], layout=layout)
fig
Now say I want the colorbar to have a title. Since plotly does not currently have a direct way to do that, if I understand correctly, I am doing this through annotations as shown here:
layout.update(
annotations=[dict(
x=1.12,
y=1.05,
align="right",
valign="top",
text='Colorbar Title',
showarrow=False,
xref="paper",
yref="paper",
xanchor="center",
yanchor="top"
)
]
)
As we can see, the colorbar title appears:
fig=go.FigureWidget(data=[trace], layout=layout)
fig
However, now say I want to place the colorbar title sideways, along the colorbar, like so:
How do I do this?
Parameter textangle do it for you. Example from plotly docs. Setting textangle=-90 rotate annotation how you want.
Code:
# import necessaries libraries
import numpy as np
import plotly.offline as py
import plotly.graph_objs as go
z = np.random.randint(1000, 11000, size=20)
# Create a trace
trace = dict(type='scatter',
x=3+np.random.rand(20),
y=-2+3*np.random.rand(20),
mode='markers',
marker=dict(color=z, colorscale='RdBu',
size=14, colorbar=dict(thickness=20)))
# Define axis_style
axis_style = dict(zeroline=False, showline=True, mirror=True)
# Specify layout style
layout = dict(width=550, height=500,
xaxis=axis_style,
yaxis=axis_style,
hovermode='closest',
)
# Update layout with annotation
layout.update(
annotations=[dict(
# Don't specify y position,because yanchor="middle" do it for you
x=1.22,
align="right",
valign="top",
text='Colorbar Title',
showarrow=False,
xref="paper",
yref="paper",
xanchor="right",
yanchor="middle",
# Parameter textangle allow you to rotate annotation how you want
textangle=-90
)
]
)
# Create FigureWidget
fig = go.FigureWidget(data=[trace], layout=layout)
# Plot fig
py.plot(fig)
Output:
For anyone who may have found this question now, there is (now?) a very easy way of adding a title to a colorbar, and to make it oriented sideways along the colorbar using the colorbar title property.
In this case, we could just update trace like so:
# Create a trace
trace = dict(type='scatter',
x=3+np.random.rand(20),
y=-2+3*np.random.rand(20),
mode='markers',
marker=dict(color=z, colorscale='RdBu', size=14,
colorbar=dict(thickness=20,
title=dict(text="Colorbar title", orient="right"))))
Documentation here: https://plotly.com/python/reference/scatter/#scatter-marker-colorbar

Categories

Resources