Administrar etiquetas de datos de gráficos en presentaciones con Python
Introducción
Las etiquetas de datos muestran información sobre las series del gráfico y los puntos de datos individuales, ayudando a los lectores a identificar valores y comprender el gráfico. Este artículo explica cómo dar formato a los valores, mostrar porcentajes, leer el texto de la etiqueta, controlar etiquetas más allá del máximo del eje, ajustar el espaciado de las etiquetas del eje de categorías y posicionar las etiquetas de los gráficos circulares.
Establecer la precisión de los datos en las etiquetas de datos del gráfico
Utilice number_format_of_values para dar formato a los valores de la serie. Este ejemplo crea un gráfico de líneas con datos predeterminados, muestra su tabla de datos y habilita las etiquetas de valor para la primera serie. El formato #,##0.00 muestra un separador de miles y dos decimales sin cambiar los valores subyacentes.
import aspose.slides as slides
import aspose.slides.charts as charts
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.LINE, 50, 50, 450, 300)
chart.has_data_table = True
series = chart.chart_data.series[0]
series.number_format_of_values = "#,##0.00"
series.labels.default_data_label_format.show_value = True
presentation.save("PrecisionOfDatalabels_out.pptx", slides.export.SaveFormat.PPTX)
Mostrar el porcentaje como etiquetas
Para un gráfico de columnas apiladas, calcule cada valor como porcentaje del total de su categoría y asigne el texto a text_frame_for_overriding. Este ejemplo utiliza los datos del gráfico predeterminados y muestra los porcentajes con dos decimales en una fuente de 8 puntos. Las categorías con un total de cero se omiten para evitar la división por cero. Recalcule el texto de la etiqueta personalizada si los datos del gráfico cambian.
import aspose.slides as slides
import aspose.slides.charts as charts
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.STACKED_COLUMN, 20, 20, 400, 400)
category_totals = [0.0] * len(chart.chart_data.categories)
for k in range(len(chart.chart_data.categories)):
for series in chart.chart_data.series:
point_value = float(series.data_points[k].value.data)
category_totals[k] += point_value
for series in chart.chart_data.series:
series.labels.default_data_label_format.show_legend_key = False
for j in range(len(series.data_points)):
label = series.data_points[j].label
if category_totals[j] == 0:
continue
point_value = float(series.data_points[j].value.data)
data_point_percent = point_value / category_totals[j] * 100
portion = slides.Portion()
portion.text = f"{data_point_percent:.2f} %"
portion.portion_format.font_height = 8
label.text_frame_for_overriding.text = ""
paragraph = label.text_frame_for_overriding.paragraphs[0]
paragraph.portions.add(portion)
label.data_label_format.show_value = True
label.data_label_format.show_series_name = False
label.data_label_format.show_percentage = False
label.data_label_format.show_legend_key = False
label.data_label_format.show_category_name = False
label.data_label_format.show_bubble_size = False
presentation.save("DisplayPercentageAsLabels_out.pptx", slides.export.SaveFormat.PPTX)
Establecer el signo de porcentaje con las etiquetas de datos del gráfico
Cuando los valores se almacenan como fracciones, use number_format para mostrar porcentajes. Establezca is_number_format_linked_to_source en False para aplicar el formato de la etiqueta de manera independiente de las celdas de origen.
Este ejemplo crea un gráfico de columnas apiladas al 100 % con series roja y azul en cuatro categorías. Cada par de valores suma 1. El formato de etiqueta 0.0% muestra 0.30 como 30.0 %, mientras que el eje vertical usa dos decimales. Ambas series utilizan texto de etiqueta blanco de 10 puntos.
import aspose.slides as slides
import aspose.slides.charts as charts
import aspose.pydrawing as drawing
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.PERCENTS_STACKED_COLUMN, 20, 20, 500, 400)
chart.axes.vertical_axis.is_number_format_linked_to_source = False
chart.axes.vertical_axis.number_format = "0.00%"
chart.chart_data.series.clear()
chart.chart_data.categories.clear()
workbook = chart.chart_data.chart_data_workbook
worksheet_index = 0
for i in range(4):
category_cell = workbook.get_cell(worksheet_index, i + 1, 0, f"Category {i + 1}")
chart.chart_data.categories.add(category_cell)
series_names = ["Reds", "Blues"]
series_colors = [drawing.Color.red, drawing.Color.blue]
values = [[0.30, 0.50, 0.80, 0.65], [0.70, 0.50, 0.20, 0.35]]
for i in range(len(series_names)):
series_cell = workbook.get_cell(worksheet_index, 0, i + 1, series_names[i])
series = chart.chart_data.series.add(series_cell, chart.type)
for j in range(4):
value_cell = workbook.get_cell(worksheet_index, j + 1, i + 1, values[i][j])
series.data_points.add_data_point_for_bar_series(value_cell)
series.format.fill.fill_type = slides.FillType.SOLID
series.format.fill.solid_fill_color.color = series_colors[i]
label_format = series.labels.default_data_label_format
label_format.show_value = True
label_format.is_number_format_linked_to_source = False
label_format.number_format = "0.0%"
label_format.text_format.portion_format.font_height = 10
label_format.text_format.portion_format.fill_format.fill_type = slides.FillType.SOLID
label_format.text_format.portion_format.fill_format.solid_fill_color.color = drawing.Color.white
presentation.save("SetDataLabelsPercentageSign_out.pptx", slides.export.SaveFormat.PPTX)
Leer el texto real de las etiquetas de datos
Utilice get_actual_label_text para obtener el texto generado por la configuración de una etiqueta de datos. Esto es útil al extraer etiquetas para informes, buscar contenido en presentaciones o validar gráficos generados. En el ejemplo a continuación, el formato de etiqueta de datos predeterminado combina el nombre de cada categoría, el nombre de la serie y el valor. Un punto formatea su valor como porcentaje, y otro utiliza texto personalizado de text_frame_for_overriding.
import aspose.slides as slides
import aspose.slides.charts as charts
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.CLUSTERED_COLUMN, 20, 20, 500, 300)
chart.chart_data.series.clear()
chart.chart_data.categories.clear()
workbook = chart.chart_data.chart_data_workbook
for i, category_name in enumerate(["Q1", "Q2"]):
category_cell = workbook.get_cell(0, i + 1, 0, category_name)
chart.chart_data.categories.add(category_cell)
north_cell = workbook.get_cell(0, 0, 1, "North")
north = chart.chart_data.series.add(north_cell, chart.type)
for i, value in enumerate([0.25, 0.75]):
value_cell = workbook.get_cell(0, i + 1, 1, value)
north.data_points.add_data_point_for_bar_series(value_cell)
south_cell = workbook.get_cell(0, 0, 2, "South")
south = chart.chart_data.series.add(south_cell, chart.type)
for i, value in enumerate([0.40, 0.60]):
value_cell = workbook.get_cell(0, i + 1, 2, value)
south.data_points.add_data_point_for_bar_series(value_cell)
for series in chart.chart_data.series:
label_format = series.labels.default_data_label_format
label_format.show_category_name = True
label_format.show_series_name = True
label_format.show_value = True
north.labels[1].data_label_format.is_number_format_linked_to_source = False
north.labels[1].data_label_format.number_format = "0%"
south.labels[0].text_frame_for_overriding.text = "Reviewed"
for series in chart.chart_data.series:
for point in series.data_points:
label = point.label
if not label.is_visible:
continue
label_text = label.get_actual_label_text()
print(f"Value: {point.value.data}; label: {label_text}")
El número almacenado en un punto de datos sigue siendo 0.75, incluso cuando su etiqueta muestra 75% junto con los nombres de categoría y serie. El texto personalizado reemplaza la etiqueta generada. get_actual_label_text devuelve la cadena de etiqueta resultante en ambos casos. Verifique is_visible por separado, como se muestra arriba, cuando solo desea extraer etiquetas visibles.
Controlar las etiquetas de datos más allá del máximo del eje
Cuando limita manualmente el rango de un eje, algunos puntos de datos pueden superar su máximo. Use show_data_labels_over_maximum para controlar si sus etiquetas de datos se muestran. Esta configuración cambia la visibilidad de la etiqueta; no modifica el rango del eje ni los valores subyacentes.
El ejemplo a continuación crea un gráfico de columnas agrupadas 2D con valores de 60 y 120. Establece is_automatic_max_value en False y max_value en 100 en el eje vertical. La primera diapositiva permite etiquetas más allá del máximo; una copia de esa diapositiva las desactiva. Ambas diapositivas se guardan en DataLabelsOverMaximum.pptx.
Active las etiquetas de valor con show_value. La configuración a nivel de gráfico no habilita la visualización de valores por sí sola ni anula la visualización desactivada de una etiqueta individual. Este ejemplo habilita los valores para toda la serie y utiliza position para colocar las etiquetas en el extremo exterior de cada columna.
import aspose.slides as slides
import aspose.slides.charts as charts
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.CLUSTERED_COLUMN, 50, 50, 600, 400)
chart.has_legend = False
chart.chart_data.series.clear()
chart.chart_data.categories.clear()
workbook = chart.chart_data.chart_data_workbook
first_category = workbook.get_cell(0, 1, 0, "Within range")
second_category = workbook.get_cell(0, 2, 0, "Above maximum")
chart.chart_data.categories.add(first_category)
chart.chart_data.categories.add(second_category)
series_name = workbook.get_cell(0, 0, 1, "Values")
series = chart.chart_data.series.add(series_name, chart.type)
first_value = workbook.get_cell(0, 1, 1, 60)
second_value = workbook.get_cell(0, 2, 1, 120)
series.data_points.add_data_point_for_bar_series(first_value)
series.data_points.add_data_point_for_bar_series(second_value)
series.labels.default_data_label_format.show_value = True
series.labels.default_data_label_format.position = charts.LegendDataLabelPosition.OUTSIDE_END
chart.axes.vertical_axis.is_automatic_max_value = False
chart.axes.vertical_axis.max_value = 100
chart.show_data_labels_over_maximum = True
second_slide = presentation.slides.add_clone(slide)
second_chart = second_slide.shapes[0]
second_chart.show_data_labels_over_maximum = False
presentation.save("DataLabelsOverMaximum.pptx", slides.export.SaveFormat.PPTX)
Las imágenes siguientes muestran las diapositivas guardadas renderizadas por Microsoft PowerPoint. Con True, la etiqueta 120 es visible en el límite superior; con False, está oculta. La etiqueta 60 sigue visible, el máximo del eje permanece en 100 y el segundo punto de datos sigue siendo 120 en ambos casos.
| show_data_labels_over_maximum = True | show_data_labels_over_maximum = False |
|---|---|
![]() |
![]() |
Chart Type
Este ejemplo utiliza un gráfico de columnas 2D con un eje de valores. Los gráficos sin eje de valores, como los circulares y de anillo, no tienen un máximo de eje que limitar de esta manera.Establecer la distancia de la etiqueta respecto a un eje
Utilice label_offset para controlar la distancia entre las etiquetas del eje de categorías y el eje. El valor es un porcentaje del tamaño máximo de fuente de las etiquetas del eje. Este ejemplo crea un gráfico de columnas agrupadas y establece el desplazamiento de la etiqueta del eje horizontal en 500. Esta configuración afecta a las etiquetas del eje de categorías más que a las etiquetas vinculadas a puntos de datos individuales.
import aspose.slides as slides
import aspose.slides.charts as charts
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.CLUSTERED_COLUMN, 20, 20, 500, 300)
chart.axes.horizontal_axis.label_offset = 500
presentation.save("SetCategoryAxisLabelDistance_out.pptx", slides.export.SaveFormat.PPTX)
Ajustar la ubicación de la etiqueta
En un gráfico circular, ajuste la posición de las etiquetas de datos para mejorar el espaciado y dejar espacio para las líneas de guía.
Este ejemplo muestra el valor del primer punto de datos, coloca su etiqueta fuera de la porción y ajusta sus desplazamientos x y y. Estos desplazamientos son relativos al ancho y la altura del gráfico, respectivamente.
import aspose.slides as slides
import aspose.slides.charts as charts
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.PIE, 50, 50, 200, 200)
series = chart.chart_data.series
label = series[0].labels[0]
label.data_label_format.show_value = True
label.data_label_format.position = charts.LegendDataLabelPosition.OUTSIDE_END
label.x = 0.71
label.y = 0.04
presentation.save("presentation.pptx", slides.export.SaveFormat.PPTX)

Dar formato a las líneas de guía
Cuando las etiquetas de los gráficos circulares están fuera de sus porciones, las líneas de guía ayudan a los lectores a asociar cada valor con la porción correcta. Un color contrastante y una línea ligeramente más gruesa pueden facilitar estas conexiones, mientras que la transparencia y un estilo de línea discontinuo mantienen las líneas visualmente discretas.
Utilice leader_lines_format para dar formato a las líneas de guía a nivel de la colección de etiquetas de datos de la serie. Los ajustes en series.labels.leader_lines_format.line se aplican a la colección, no a una etiqueta individual.
Este ejemplo crea un gráfico circular con datos predeterminados, muestra los valores fuera de las porciones y habilita show_leader_lines. Mueve dos etiquetas más lejos de sus porciones usando los desplazamientos x y y, expresados como fracciones del ancho y la altura del gráfico. No se requiere una presentación de entrada.
El fill_format de la línea establece un color azul sólido con un valor alfa de 191 sobre 255, lo que equivale a aproximadamente un 25 % de transparencia. width define el grosor en 2 puntos, y dash_style convierte la línea en discontinua.
import aspose.slides as slides
import aspose.slides.charts as charts
import aspose.pydrawing as drawing
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.PIE, 80, 50, 560, 400)
chart.has_legend = False
series = chart.chart_data.series[0]
label_format = series.labels.default_data_label_format
label_format.show_value = True
label_format.position = charts.LegendDataLabelPosition.OUTSIDE_END
label_format.show_leader_lines = True
# Mueve dos etiquetas más lejos de sus porciones.
series.labels[0].x = 0.10
series.labels[0].y = -0.05
series.labels[1].x = -0.10
series.labels[1].y = 0.05
line = series.labels.leader_lines_format.line
line.fill_format.fill_type = slides.FillType.SOLID
line.fill_format.solid_fill_color.color = drawing.Color.from_argb(191, 30, 90, 160)
line.width = 2
line.dash_style = slides.LineDashStyle.DASH
presentation.save("FormattedLeaderLines.pptx", slides.export.SaveFormat.PPTX)
Habilitar las líneas de guía no garantiza que aparezca una línea para cada etiqueta. La visibilidad depende de la posición de la etiqueta y del comportamiento de distribución del gráfico. En este ejemplo, las dos etiquetas desplazadas tienen líneas de guía visibles; las etiquetas que permanecen cerca de sus porciones no las requieren.
La imagen siguiente muestra el archivo FormattedLeaderLines.pptx guardado y renderizado con Aspose.Slides:

Agregar varias filas de etiquetas de datos encima de un gráfico de columnas
Este ejemplo crea un gráfico de columnas con dos filas de etiquetas de datos sobre el área de trazado. La Serie A muestra las columnas visibles, mientras que la Serie B y la Serie C proporcionan las etiquetas adicionales. Sus columnas se ocultan eliminando el relleno y el contorno. La propiedad overlap alinea las tres series con los mismos centros de categoría.
Los ajustes de plot_area reservan espacio para las filas de etiquetas. Después de que validate_chart_layout calcula las posiciones predeterminadas, los desplazamientos x y y conservan la alineación horizontal y aplican desplazamientos verticales para organizar las etiquetas en dos filas. Los números siguen siendo etiquetas de datos vinculadas a los valores de la serie; solo los encabezados de fila son formas de texto independientes.
import aspose.slides as slides
import aspose.slides.charts as charts
import aspose.pydrawing as drawing
with slides.Presentation() as presentation:
slide = presentation.slides[0]
chart = slide.shapes.add_chart(charts.ChartType.CLUSTERED_COLUMN, 40, 40, 640, 200)
chart.has_title = False
chart.has_legend = False
chart.text_format.portion_format.font_height = 12
chart.chart_data.series.clear()
chart.chart_data.categories.clear()
workbook = chart.chart_data.chart_data_workbook
workbook.clear(0)
categories = ["North", "South", "East", "West"]
series_names = ["Series A", "Series B", "Series C"]
series_values = [
[35, 42, 28, 47],
[22, 31, 19, 26],
[12, 16, 14, 18]
]
for category_index, category_name in enumerate(categories):
category_cell = workbook.get_cell(0, category_index + 1, 0, category_name)
chart.chart_data.categories.add(category_cell)
for series_index, series_name in enumerate(series_names):
series_cell = workbook.get_cell(0, 0, series_index + 1, series_name)
series = chart.chart_data.series.add(series_cell, charts.ChartType.CLUSTERED_COLUMN)
for category_index in range(len(categories)):
value_cell = workbook.get_cell(0, category_index + 1, series_index + 1, series_values[series_index][category_index])
series.data_points.add_data_point_for_bar_series(value_cell)
if series_index > 0:
# Ocultar las columnas de B y C, pero mantener sus etiquetas de datos.
series.format.fill.fill_type = slides.FillType.NO_FILL
series.format.line.fill_format.fill_type = slides.FillType.NO_FILL
label_format = series.labels.default_data_label_format
label_format.show_value = True
label_format.text_format.portion_format.font_height = 12
label_fill = label_format.text_format.portion_format.fill_format
label_fill.fill_type = slides.FillType.SOLID
label_fill.solid_fill_color.color = drawing.Color.black
label_format.position = charts.LegendDataLabelPosition.INSIDE_BASE
# Alinear las tres series con los mismos centros de categoría.
chart.chart_data.series[0].parent_series_group.overlap = 100
# Usar menos líneas de cuadrícula para este ejemplo compacto.
chart.axes.vertical_axis.is_automatic_major_unit = False
chart.axes.vertical_axis.major_unit = 10
# Reservar espacio encima del área de trazado para dos filas de etiquetas de datos.
chart.plot_area.layout_target_type = charts.LayoutTargetType.INNER
chart.plot_area.x = 0.15
chart.plot_area.y = 0.32
chart.plot_area.width = 0.80
chart.plot_area.height = 0.48
chart.validate_chart_layout()
for series_index in range(1, len(series_names)):
series = chart.chart_data.series[series_index]
row_top = 0.15 if series_index == 1 else 0.03
for category_index in range(len(categories)):
data_label = series.data_points[category_index].label
# Mantener la posición horizontal predeterminada. Y es un desplazamiento desde
# la posición predeterminada de la etiqueta, expresado como una fracción de la altura del gráfico.
data_label.x = 0
data_label.y = row_top - data_label.actual_y / chart.height
# Solo el encabezado de fila es una forma de texto independiente.
row_heading = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, chart.x, chart.y + row_top * chart.height, 85, 18)
row_heading.fill_format.fill_type = slides.FillType.NO_FILL
row_heading.line_format.fill_format.fill_type = slides.FillType.NO_FILL
row_heading.add_text_frame(series_names[series_index])
row_heading.text_frame.text_frame_format.margin_top = 0
row_heading.text_frame.text_frame_format.margin_bottom = 0
heading_format = row_heading.text_frame.paragraphs[0].portions[0].portion_format
heading_format.font_height = 12
heading_format.fill_format.fill_type = slides.FillType.SOLID
heading_format.fill_format.solid_fill_color.color = drawing.Color.black
presentation.save("multiple-rows-of-labels.pptx", slides.export.SaveFormat.PPTX)

Preguntas frecuentes
¿Cómo puedo evitar que las etiquetas de datos se superpongan en gráficos densos?
Combine la colocación automática de etiquetas, líneas de guía y una reducción del tamaño de la fuente; si es necesario, oculte algunos campos (por ejemplo, la categoría) o muestre etiquetas solo para los valores extremos o puntos clave.
¿Cómo puedo desactivar las etiquetas solo para valores cero, negativos o vacíos?
Filtre los puntos de datos antes de habilitar las etiquetas y desactive la visualización para los valores 0, los valores negativos o los valores ausentes según una regla definida.
¿Cómo puedo garantizar un estilo de etiqueta coherente al exportar a PDF/imágenes?
Establezca explícitamente la familia y el tamaño de la fuente y verifique que la fuente esté disponible en el entorno de renderizado para evitar sustituciones.

