2

I have the following code which generates a 3D plot. I am trying to label the plot lines, but they are not ending up where I expect them.

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

# Data
names = [
    "A", "B", "C", "D", "E", "F",
    "G", "H", "I", "J", "K", "L"
]
wins = [
    [0, 14, 20, 24, 29, 33, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39],
    [0, 7, 13, 17, 23, 27, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
    [0, 5, 8, 11, 15, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19],
    [0, 7, 11, 17, 20, 25, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29],
    [0, 9, 14, 22, 29, 36, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    [0, 6, 10, 16, 20, 24, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29],
    [0, 7, 13, 20, 26, 31, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34],
    [0, 10, 13, 18, 24, 29, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33],
    [0, 5, 11, 13, 16, 21, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26],
    [0, 12, 15, 18, 21, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
    [0, 9, 11, 12, 17, 20, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26],
    [0, 15, 20, 25, 27, 33, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37],
]
weeks = [f"Week{i+1}" for i in range(18)]  # X-axis categories (nb of weeks)

# Convert names into numerical indices for the Y-axis
x = np.arange(len(weeks))      # X-axis 
y = np.arange(len(names))      # Y-axis 
wins_array = np.array(wins)    # wins accumulated per weeks and per names

# Create a 3D plot
fig = plt.figure(figsize=(18, 18))
ax = fig.add_subplot(111, projection='3d')

# Plot each line and add labels
for i, y_week in enumerate(y):
    ax.plot(x, wins_array[i], zs=y_week, zdir='x', label=weeks[i])
    # Add shaded area below the line
    ax.bar(x, wins_array[i], zs=y_week, zdir='x', alpha=0.1)
    # Add labels directly on the curves
    for j, my_label in enumerate(wins_array[i]):
        ax.text(i, my_label, y_week, f"{my_label}", color="red", fontsize=8, ha="center")

# Customize labels
ax.set_zlabel('Wins')              # Z-axis is wins
ax.set_xticks(y)                   # X-ticks are names
ax.set_xticklabels(names, rotation=45)  # Name labels on X-axis
ax.set_yticks(x)                   # Y-ticks are weeks
ax.set_yticklabels(weeks)          # Week labels on Y-axis

plt.show()

This is the current result:

The result I am trying to achieve is something like this:

How do I fix my code to achieve my desired result?

2 Answers 2

1

It is easier to separate the drawing and the text annotation:

# Plot each line 
for i, y_week in enumerate(y):
    ax.plot(x, wins_array[i], zs=y_week, zdir='x', label=weeks[i])
    # Add shaded area below the line
    ax.bar(x, wins_array[i], zs=y_week, zdir='x', alpha=0.1)

# Add labels directly on the curves
for i in y:
    for j, k in zip(x, wins_array[i]):
        ax.text(i, j, k, f"{k}", color="red", fontsize=8, ha="center")

res

Sign up to request clarification or add additional context in comments.

Comments

0

You can add text at the coordinate where you want to display the value with Matplotlib's text() function

ax.text(x_coord, y_coord, z_coord, value, color='red', fontsize=10)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.