1

I am using Matplotlib to make a stacked bar chart, and want to display a label of the clicked data.

I wrote a code to display the labels for a simple line graph. When I try to do the same with a bar chart, and it does not work. The below is the code that works with a line graph.

import numpy as np
import matplotlib.pyplot as plt

# plots port counts per address as a stacked bar graph
fig=plt.figure()
ax=fig.add_subplot(111)
text=ax.text(0,0, '', va='baseline', ha='left')

# plot 
y=np.array([[1,2,3],[4,5,6]])

for i in range(2):
    ax.plot(y[i, :], gid=i)

def on_click(event):
    for curve in ax.get_lines():
        if curve.contains(event)[0]: gid=curve.get_gid()
    text.set_text('Class %s' % gid)

fig.canvas.mpl_connect('button_press_event', on_click)

When I click a line, its label (gid) is displayed as shown in the below picture. enter image description here

The next code works in drawing a stacked bar graph, but does not display the labels. Although no error message is returned, label cannot be obtained and displayed.

# plots port counts per address as a stacked bar graph
fig=plt.figure()
ax=fig.add_subplot(111)
text=ax.text(0,0, '', va='baseline', ha='left')
bottom=np.array([0,0,0])

# plot 
x_pos=np.arange(3)
y=np.array([[1,2,3],[1,3,5]])

for i in range(2):
    ax.bar(x_pos, y[i, :], align='center', bottom=bottom, alpha=0.5, gid=i)

    # update the bar bases for the next iteration
    bottom=np.add(bottom,y[i, :] )

def on_click(event):
    gid='-'
    for curve in ax.get_lines():
        gid='TEST'
        if curve.contains(event)[0]: 
            gid=curve.get_gid()
    text.set_text('Class %s' % gid)

fig.canvas.mpl_connect('button_press_event', on_click)

I am assuming that ax.bar does not create lines to be retuned by get_lines, consequently it exits for curve in ax.get_lines() loop with 0 iterations, because of how the text is set when clicking the chart as shown in the below picture.

enter image description here

I would like to know how I can display the label by clicking a stacked bar graph.

Hikari A
  • 63
  • 2
  • 8

1 Answers1

0

The concept of finding out which artist the mouse event is contained in is usefull when using hovering, as e.g. How to annotate the values of X and Y while hovering mouse over the bar graph

In contrast, here you want to click on the bars. This is accomplished with a "picker"; and in fact there is no difference between lines or bars in that case.

So the following works for both cases. It shows "Class bar: 0" when the first bars are clicked and "Class line: 0" for the first line.

import numpy as np
import matplotlib.pyplot as plt

# plots port counts per address as a stacked bar graph
fig=plt.figure()
ax=fig.add_subplot(111)
text=ax.text(0,0, '', va='baseline', ha='left')
bottom=np.array([0,0,0])

# plot 
x_pos=np.arange(3)
y=np.array([[1,2,3],[1,3,5]])

for i in range(2):
    ax.bar(x_pos, y[i, :], align='center', bottom=bottom, alpha=0.5, gid=f"bar: {i}", picker=4)
    ax.plot(y[i, :], gid=f"line: {i}", picker=4)
    # update the bar bases for the next iteration
    bottom=np.add(bottom,y[i, :] )

def on_click(event):
    text.set_text(f"Class {event.artist.get_gid()}")
    fig.canvas.draw_idle()

fig.canvas.mpl_connect('pick_event', on_click)

plt.show()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712