Convert plotly marker from continuous to discrete - python

Following is my input file i'm trying to display on a map using plotly.
data.csv
lat,long,type
-7.80715,110.371203,1
-7.791087,110.368346,3
-7.778744,110.365107,7
-7.77877,110.365379,4
The script works but the scale is displayed in a continuous format. I tried to convert the column type to text as mentioned here but I couldn't get it to work. Is there a easier way to fix this problem?
df = pd.read_csv("data.csv").dropna()
fig = go.Figure(go.Scattermapbox(
lat=df["lat"].tolist(),
lon=df["long"].tolist(),
mode='markers',
text=df['type'].tolist(),
marker=go.scattermapbox.Marker(
size=10,
color=df['type'],
showscale=True
),
))
fig.show()

If you want to specify a discrete color, you can either deal with it directly as a list of color specifications, or you can specify the default color name in plotly_express.
import plotly.graph_objects as go
import plotly.express as px
mapbox_access_token = open("mapbox_api_key.txt").read()
colors = px.colors.qualitative.D3
fig = go.Figure(go.Scattermapbox(
lat=df["lat"].tolist(),
lon=df["long"].tolist(),
mode='markers',
text=df['type'].tolist(),
marker=go.scattermapbox.Marker(
size=10,
color=colors,
showscale=False
),
))
fig.update_layout(
autosize=False,
height=450,
width=1000,
mapbox=dict(
accesstoken=mapbox_access_token,
style="outdoors",
center=dict(
lat=-7.78,
lon=110.365
),
zoom=10),
showlegend = False
)
fig.show()

Related

Change plotly express "color" variable with button

I would like to create a plotly plot where I can change the value of the plotly express color argument via a button. I am using plotly.express.scatter for this.
For example, the initial plot shown is px.scatter(df, "sepal_length", "sepal_width", color="species"). Changing from "species" to "petal length" in a dropdown menu would update the plot so that instead color="petal_length". If it makes a difference, "species" uses the default discrete color sequence while "petal_length" uses the default continuous color scale.
The code I have so far makes the initial plot and dropdown buttons, but choosing the buttons has no effect. I don't understand how to get the plotly express color argument passed through this Plotly.update interface.
import plotly.express as px
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv")
fig = px.scatter(df, "sepal_length", "sepal_width", color="species")
fig.update_layout(
updatemenus=[
dict(
buttons=list([
dict(
args=["color", "species"],
label="species",
method="update"
),
dict(
args=["color", "petal_length"],
label="petal length",
method="update"
),
]),
showactive=True,
x=0.05,
xanchor="left",
y=1.06,
yanchor="top"
),
]
)
fig.update_layout(
annotations=[
dict(text="color", x=0.015, xref="paper", y=1.05, yref="paper",
align="left", showarrow=False),
])
fig.show()
For color='species', three graphs are internally created for each categorical variable. And color='petal_length' consists of a single graph data. So, it is possible to handle this by setting the drop-down to show/hide the graph. The actual code reuses the data created by express.scatter. The data for each graph will be configured in a graph object; three will be shown and one will be hidden. Set the button to restyle as a function of the button.
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv")
fig1 = px.scatter(df, "sepal_length", "sepal_width", color="species")
fig2 = px.scatter(df, "sepal_length", "sepal_width", color="petal_length")
fig = go.Figure()
fig.add_trace(go.Scatter(fig1.data[0], visible=True))
fig.add_trace(go.Scatter(fig1.data[1], visible=True))
fig.add_trace(go.Scatter(fig1.data[2], visible=True))
fig.add_trace(go.Scatter(fig2.data[0], visible=False))
fig.update_layout(
updatemenus=[
dict(
buttons=list([
dict(
args=["visible", [True,True,True,False]],
label="species",
method="restyle"
),
dict(
args=["visible", [False,False,False,True]],
label="petal length",
method="restyle"
),
]),
showactive=True,
x=0.05,
xanchor="left",
y=1.2,
yanchor="top"
),
]
)
fig.update_layout(
annotations=[
dict(text="color", x=0.01, xref="paper", y=1.16, yref="paper",
align="left", showarrow=False),
])
fig.update_layout(xaxis_title_text='sepal_length', yaxis_title_text='sepal_width', legend_title_text='species')
fig.show()

Setting boundaries for datetime x axis on Plotly (Python)

I have to plot some chronologically-ordered values (one value per month, in my case) on a Plotly (Python) graph. Also, I have to add a "end of period label" (i.e. a marker with text indicating the last value of the series) that has to be positioned at 'middle right'.
A working example would be something like this:
import pandas as pd
import numpy as np
import plotly.graph_objects as go
date_range = pd.to_datetime(pd.date_range(start='1/1/2013', end='9/1/2022', freq='M').tolist()).date
values = np.random.randint(100, size=len(date_range)).tolist()
fig = go.Figure(
)
fig.add_trace(go.Scatter(
showlegend=False,
x=date_range,
y=values,
mode='lines',
line=dict(
width=2,
color="red",
)
)
)
fig.add_trace(go.Scatter(
showlegend=False,
x=[date_range[-1]],
y=[values[-1]],
text=[values[-1]],
textposition='middle right',
texttemplate="%{text:.3f}",
mode='markers+text',
line=dict(
width=2,
color="red",
)
)
)
fig.update_layout(
xaxis=dict(
tickformat="%m\n<b>%Y", dtick="M3",
)
)
which produces the following plot:
I am facing the following problem: the end of period label "extends" beyond the last value of the date range and makes the x axis go into the green area, which are all undesired months (for example, those that extend beyond the last value of the date range and into 2023).
I tried several things to "erase" or delete that undesired part of the x axis, but nothing worked properly: either the end of period label was cut in half or the whole x axis disappeared.
Thank you in advance for any help or suggestion.
as per #r0beginners comments
given text is outside graph area use an annotation for the text
make marker scatter just mode=markers
explicitly state xaxis range range=date_range[[0,-1]]
import pandas as pd
import numpy as np
import plotly.graph_objects as go
date_range = pd.to_datetime(
pd.date_range(start="1/1/2013", end="9/1/2022", freq="M").tolist()
).date
values = np.random.randint(100, size=len(date_range)).tolist()
fig = go.Figure()
fig.add_trace(
go.Scatter(
showlegend=False,
x=date_range,
y=values,
mode="lines",
line=dict(
width=2,
color="red",
),
)
)
fig.add_trace(go.Scatter(
showlegend=False,
x=[date_range[-1]],
y=[values[-1]],
mode='markers',
marker_size=15
)
)
fig.add_annotation(
x = date_range[-1],
y = values[-1],
text = values[-1],
xshift=10,
yshift=0,
showarrow=False
)
fig.update_layout(
xaxis=dict(
tickformat="%m\n<b>%Y",
dtick="M3",
range=date_range[[0,-1]]
)
)

How to add an extra point over a boxplot graph with plotly?

I am trying to overlay a point over a boxplot with Plotly and Python. I am able to add two traces to the same graph, but I couldn't find a way to make the extra point closer to the boxplot.
This is the image I get:
and the code that generates it is:
x = np.fromiter(duplicates.values(), dtype=float)
fig = go.Figure()
fig.update_layout(autosize=False, width=400, height=150, paper_bgcolor="White", plot_bgcolor='rgba(0,0,0,0)',
hovermode=False, margin=dict(l=10, r=10, b=10, t=10, pad=4),
boxmode='group', boxgroupgap=0.25,
boxgap=0.25,
)
fig.add_trace(go.Box(x=x, showlegend=False))
fig.add_trace(go.Scatter(x=np.array(duplicates[sample_id]), y=np.array(0), mode='markers', showlegend=False))
fig.update_xaxes(title='')
fig.update_yaxes(showticklabels=False)
my_div = plotly.offline.plot(fig, output_type='div',
show_link=False,
config=dict(
displayModeBar=False
))

in plotly show text by default for map when saving to image

I have created a plotly map and added some lat, lon points on it with marker and text and it shows fine when viewed as interactive map on Jupyter notebook but when I'm saving that map as PNG text doesn't show.
here is my code
import plotly.graph_objects as go
mapbox_access_token = open(".mapbox_token").read()
fig = go.Figure(go.Scattermapbox(
lat=['45.5017'],
lon=['-73.5673'],
mode='markers',
marker=go.scattermapbox.Marker(
size=14
),
text=['Montreal'],
))
fig.update_layout(
hovermode='closest',
mapbox=dict(
accesstoken=mapbox_access_token,
bearing=0,
center=go.layout.mapbox.Center(
lat=45,
lon=-73
),
pitch=0,
zoom=5
)
)
fig.show()
Expected output
Output I get when image is saved
i just want all text/annotation visible after saving image
The hover function can be enabled by moving the mouse cursor closer. So if you want to save a graph, that information will not be saved. If you add text information to the map as annotations, it will be saved in the image. The position, text color, font family, and size are specified for the annotation. The display format can be standardized by using texttemplate.
import plotly.graph_objects as go
mapbox_access_token = open("mapbox_api_key.txt").read()
fig = go.Figure(go.Scattermapbox(
lat=['45.5017'],
lon=['-73.5673'],
mode='markers+text',
marker=go.scattermapbox.Marker(
size=14
),
text=['Montreal'],
textfont={'color':'royalblue', 'family':'Arial','size':16},
textposition='bottom right',
texttemplate='(%{lat},%{lon})%{text}'
))
fig.update_layout(
hovermode='closest',
mapbox=dict(
accesstoken=mapbox_access_token,
bearing=0,
center=go.layout.mapbox.Center(
lat=45,
lon=-73
),
pitch=0,
zoom=5
)
)
fig.show()

Plot.ly draw reference lines on subplot?

I wrote the function below to make a vertical reference line on a figure.
from plotly import graph_objects as go
import plotly.express as px
def add_vline(fig, x=0, text=None):
if text is None:
text = str(x)
fig.update_layout(
shapes=list(fig.layout.shapes) + [
go.layout.Shape(
type="line",
x0=x,
x1=x,
yref="paper",
y0=0,
y1=1,
line=dict(
color="Red",
width=2
)
)
],
annotations=list(fig.layout.annotations) + [
go.layout.Annotation(
x=x,
y=0.5,
yref="paper",
text=text
)
]
)
gapminder = px.data.gapminder()
for continent in gapminder.continent.unique():
fig = px.histogram(gapminder, x="lifeExp", title=f'Life expectancy in {continent}')
add_vline(fig, gapminder[gapminder.continent == continent].lifeExp.median())
# add_figure_to_subplot() ?
I can view these individually, but I'd like to make a report with all these generated figures shown in order. How can I either make a subplot of these figure objects, or replicate these plots within subplot traces?

Categories