Reputation: 248
I have been searching for this solution in the official site of Plotly, Plotly forum and this forum for 3 days, and did not find it. I tried these following quetsions:
For example, here is the image:
You can see that Angola’s, Cabo Verde’s, Mozambique’s, Portugal’s, and São Tomé’s trace lines are overlapping each other on the Y-axis. On the X-axis, these markers of the numbers of population of all these countries between the years 2022 and 2025 are overlapping each other.
Here is the CSV data:
"Country","2022","2024","2025","2030","2040","2050"
"Angola","35.6M","37.9M","39M","45.2M","59M","74.3M"
"Brasil","210M","212M","213M","216M","219M","217M"
"Cabo Verde","520K","525K","527K","539K","557K","566K"
"Moçambique","32.7M","34.6M","35.6M","40.8M","52.1M","63.5M"
"Portugal","10.4M","10.4M","10.4M","10.3M","10.1M","9.8M"
"São Tomé and Príncipe","226K","236K","240K","265K","316K","365K"
And here is the simple and small code:
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
fig = go.Figure()
df = pd.read_csv('assets/csv/luso_pop_proj_who_data.csv')
for col in df.columns[1:]:
df[col] = df[col].replace({"M": "e+06", "K": "e+03"}, regex = True).astype(float)
df_long = df.melt(id_vars = "Country", var_name = "Year", value_name = "Population")
df_long["Year"] = df_long["Year"].astype(int)
fig = px.line(
df_long,
color = "Country",
height = 600,
labels =
{
"Country": "País",
"Population": "Número de população",
"Year": "Ano"
},
template = "seaborn",
text = "Population",
title = "Projeção da população nos países lusófonos (2022-2050)",
width = 1200,
x = "Year",
y = "Population",
)
fig.update_traces(
hovertemplate = None,
mode = "lines+markers+text",
showlegend = True,
textfont = dict(size = 15),
textposition = "top center",
texttemplate = "%{text:.3s}",
)
fig.update_layout(
margin = dict(l = 0, r = 0, b = 10, pad = 0),
hovermode = False
)
fig.show(
config = config
)
I have been testing with these following codes:
fig = px.line(
facet_row_spacing = 1,
)
fig.update_traces(
line = dict(
backoff = 10,
),
)
fig.update_xaxes(
automargin = True,
autorange = False,
fixedrange = True,
range = ['2020', '2050'],
)
fig.update_yaxes(
automargin = True,
fixedrange = True,
)
fig.update_layout(
margin = dict(l = 0, r = 0, b = 10, pad = 0),
)
I expected that, with these configurations, the trace lines moved away with the increasing space, but it did not give any effect.
Upvotes: 2
Views: 38
Reputation: 35230
One way to deal with data adjacencies like this is to make the y-axis logarithmic, which sometimes solves the problem, but in your case the effect is limited. My suggestion is to create a subplot with three groups of numbers. Besides, minimise the gaps between the graphs to make them appear as one graph. The key to setting up the subplot is to share the x-axis and the graph ratio. Finally, limits are set for each y-axis to make the text annotations easier to read.
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig = make_subplots(rows=3, cols=1, shared_xaxes=True, vertical_spacing=0, row_heights=[0.3,0.4,0.3])
groups = {'Angola':2, 'Brasil':1, 'Cabo Verde':3, 'Moçambique':2, 'Portugal':2, 'São Tomé and Príncipe':3}
for k,v in zip(groups.keys(), groups.values()):
dff = df_long[df_long['Country'] == k]
text_position = 'bottom center' if k == 'Moçambique' else 'top center'
fig.add_trace(go.Scatter(
x=dff['Year'],
y=dff['Population'],
name=k,
text=dff['Population'],
showlegend = True,
hovertemplate = None,
textfont = dict(size = 15),
textposition = text_position,
texttemplate = "%{text:.3s}",
mode='lines+markers+text'
),row=v, col=1)
fig.update_yaxes(range=[210_000_000,222_000_000],row=1, col=1)
fig.update_yaxes(range=[10_000_000,80_000_000],row=2, col=1)
fig.update_yaxes(range=[200_000,620_000],row=3, col=1)
fig.update_layout(margin=dict(t=20, b=0, l=0,r=0))
fig.show()
Upvotes: 1