Сложность отображения значений гистограммы в виде аннотации в PlotlyPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Сложность отображения значений гистограммы в виде аннотации в Plotly

Сообщение Anonymous »

Из-за позиционирования, которое я хочу использовать, добиться этого с помощью встроенных «текста» и «текстовой позиции» невозможно. Поэтому я должен создать одну аннотацию для каждого из этих столбцов.
На реальном графике, который я пытаюсь построить, используются даты с небольшими пробелами (несколько лет отсутствуют в хронологическом порядке), но по какой-то странной причине я способен заставить его работать при использовании строки в качестве индексного столбца. При использовании значений (реальных значений, которые у меня есть) это работает неправильно, и между столбцами возникают странные промежутки.
Проверив мой код и прочитав комментарии, вам будет легче понять, что я имею в виду:

Код: Выделить всё

import plotly.graph_objects as go
import pandas as pd

# Dummy Data for Global, China's, USA's, and India's Population (1970-2020)
years = [1975, 1980, 1990, 2000, 2020, 2040] #This is the right values I wanna use
# years = ['1975a', '1980a', '1990a', '2000a', '2020a', '2040a'] #Those values work cause adding 'a' prevents the script from turning those strs into int
global_population = [3.7, 4.4, 5.3, 6.1, 6.9, 7.8]  # In billions
china_population = [0.83, 0.98, 1.14, 1.26, 1.34, 1.41]  # In billions
usa_population = [0.205, 0.227, 0.249, 0.282, 0.309, 0.331]  # In billions (dummy values)
india_population = [0.554, 0.698, 0.873, 1.05, 1.21, 1.38]  # In billions (dummy values)

# Creating DataFrame
data = pd.DataFrame({
'Year': years,
'Global Population (Billions)': global_population,
'China Population (Billions)': china_population,
'USA Population (Billions)': usa_population,
'India Population (Billions)': india_population
})

# Function to add annotations with arrows
def add_annotations_with_arrows(fig, x_values, y_values, xshift=10, yshift=0.03, font_size=10, font_color="white", arrow_size=1):
for i, x in enumerate(x_values):
fig.add_annotation(
x=str(x), #Forcing it to use as str to prevent errors
y=y_values[i] + yshift,  # Position text slightly above each bar
text=f"{y_values[i]:.2f}",  # Format text to 2 decimal places
showarrow=True,  # Show the arrow
arrowhead=0,  # Type of arrowhead
arrowsize=arrow_size,  # Size of the arrow
ax=0,  # X position of the arrow tip
ay=-20,  # Y position of the arrow tip (controls how far the text is above the bar)
font=dict(size=font_size, color=font_color),  # Set font size and color
xshift=xshift,  # Shift the text slightly to the right
align='center',  # Align text to the center
arrowcolor=font_color  # Match arrow color to font color
)

# Create the bar graph with Global, China, USA, and India's population
def create_bar_graph_with_usa_india(data, sig_val=2, title="Population Comparison (1970-2020)", x_label="Year", y_label="Population (Billions)"):
fig = go.Figure()

# Add bar for Global Population
fig.add_trace(go.Bar(
x=data['Year'].astype(str),
y=data['Global Population (Billions)'],
name='Global Population',
marker_color='blue',
text=[f"{val:.2f}B" for val in data['Global Population (Billions)']],
textposition='none'
))

# Add bar for China's Population
fig.add_trace(go.Bar(
x=data['Year'].astype(str),
y=data['China Population (Billions)'],
name="China's Population",
marker_color='red',
text=[f"{val:.2f}B" for val in data['China Population (Billions)']],
textposition='none'
))

# Add bar for USA's Population
fig.add_trace(go.Bar(
x=data['Year'].astype(str),
y=data['USA Population (Billions)'],
name="USA's Population",
marker_color='green',
text=[f"{val:.2f}B" for val in data['USA Population (Billions)']],
textposition='none'
))

# Add bar for India's Population
fig.add_trace(go.Bar(
x=data['Year'].astype(str),
y=data['India Population (Billions)'],
name="India's Population",
marker_color='orange',
text=[f"{val:.2f}B"  for val in data['India Population (Billions)']],
textposition='none'
))

# Adjust layout for better display
fig.update_layout(
barmode='group',  # Group bars for each year side by side
title=title,
xaxis=dict(title=x_label),
yaxis=dict(title=y_label, range=[0, max(data['Global Population (Billions)']) * 1.1]),  # Adjust Y-axis
plot_bgcolor='white',
legend=dict(title="Population Type"),
font=dict(size=12)
)

# Add annotations for Global Population
add_annotations_with_arrows(
fig, data['Year'], data['Global Population (Billions)'], xshift=-60, yshift=0.05, font_size=10, font_color="blue"
)

# Add annotations for China's Population
add_annotations_with_arrows(
fig, data['Year'], data['China Population (Billions)'], xshift=-10, yshift=0.05, font_size=10, font_color="red"
)

# Add annotations for USA's Population
add_annotations_with_arrows(
fig, data['Year'], data['USA Population (Billions)'], xshift=40, yshift=0.05, font_size=10, font_color="green"
)

# Add annotations for India's Population
add_annotations_with_arrows(
fig, data['Year'], data['India Population (Billions)'], xshift=100, yshift=0.05, font_size=10, font_color="orange"
)

return fig

# Generate the figure
fig = create_bar_graph_with_usa_india(data)

# Show the figure
fig.show()
Это график, который я получаю при использовании данных в виде «строка + a» — это желаемый результат

Код: Выделить всё

years = ['1975a', '1980a', '1990a', '2000a', '2020a', '2040a']
Изображение

Однако при использовании реальных данных (отформатированных как int) форматирование полностью теряется

Код: Выделить всё

years = [1975, 1980, 1990, 2000, 2020, 2040]
Изображение

Я знаю, что аннотации мешают форматированию, потому что когда я отключаю эти блоки кода

Код: Выделить всё

# Add annotations for Global Population
add_annotations_with_arrows(
fig, data['Year'], data['Global Population (Billions)'], xshift=-60, yshift=0.05, font_size=10, font_color="blue"
)

# Add annotations for China's Population
add_annotations_with_arrows(
fig, data['Year'], data['China Population (Billions)'], xshift=-10, yshift=0.05, font_size=10, font_color="red"
)

# Add annotations for USA's Population
add_annotations_with_arrows(
fig, data['Year'], data['USA Population (Billions)'], xshift=40, yshift=0.05, font_size=10, font_color="green"
)

# Add annotations for India's Population
add_annotations_with_arrows(
fig, data['Year'], data['India Population (Billions)'], xshift=100, yshift=0.05, font_size=10, font_color="orange"
)
Он снова работает правильно, даже если «годы» отформатированы как int.
Я пытался заставить его читать как строку, но безуспешно, поэтому любая помощь будет очень полезна. оценен.
p.s: Это псевдокод, который я написал очень подробно, чтобы попытаться выявить и исправить проблему. Извините, если это выглядит неаккуратно.

Подробнее здесь: https://stackoverflow.com/questions/790 ... -in-plotly
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»