1

I am working on product sell analysis project and for that i have created one donut chart for different products.Now my question is,how to add copy id button near the legends(or anywhere in the graph window) of doughnut chart so that user can copy product id directly from there

Expected output

enter image description here

Code

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))

products = ["id 11111",
          "id 22222",
          "id 33333",
          "id 44444",
          "id 55555",
          "id 66666"]

data = [225, 90, 50, 60, 100, 5]

wedges, texts = ax.pie(data, wedgeprops=dict(width=0.5), startangle=-40)

bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
kw = dict(arrowprops=dict(arrowstyle="-"),
          bbox=bbox_props, zorder=0, va="center")

for i, p in enumerate(wedges):
    ang = (p.theta2 - p.theta1)/2. + p.theta1
    y = np.sin(np.deg2rad(ang))
    x = np.cos(np.deg2rad(ang))
    horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
    connectionstyle = "angle,angleA=0,angleB={}".format(ang)
    kw["arrowprops"].update({"connectionstyle": connectionstyle})
    ax.annotate(products[i], xy=(x, y), xytext=(1.35*np.sign(x), 1.4*y),
                horizontalalignment=horizontalalignment, **kw)

ax.set_title("Matplotlib Products Sell: A donut")

plt.show()

output

enter image description here

Mayur Satav
  • 985
  • 2
  • 12
  • 32

1 Answers1

1

The following code allows you to click on the annotation box and copies the content to the clipboard.

I use pandas.io.clipboard for doing so, as per this answer.

import numpy as np
import matplotlib.pyplot as plt
from pandas.io.clipboard import copy


def onclick(event):
    copy(event.artist.get_text())


fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
cid = fig.canvas.mpl_connect('pick_event', onclick)

products = ["id 11111",
            "id 22222",
            "id 33333",
            "id 44444",
            "id 55555",
            "id 66666"]

annotations = []

data = [225, 90, 50, 60, 100, 5]

wedges, texts = ax.pie(data, wedgeprops=dict(width=0.5), startangle=-40)

bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
kw = dict(arrowprops=dict(arrowstyle="-"),
          bbox=bbox_props, zorder=0, va="center")

for i, p in enumerate(wedges):
    ang = (p.theta2 - p.theta1) / 2. + p.theta1
    y = np.sin(np.deg2rad(ang))
    x = np.cos(np.deg2rad(ang))
    horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
    connectionstyle = "angle,angleA=0,angleB={}".format(ang)
    kw["arrowprops"].update({"connectionstyle": connectionstyle})
    ax.annotate(products[i], xy=(x, y), xytext=(1.35 * np.sign(x), 1.4 * y),
                horizontalalignment=horizontalalignment, picker=True, **kw)

ax.set_title("Matplotlib Products Sell: A donut")

plt.show()
Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
  • Hey @Diziet Asahi thanks for your answer, i tried whatever you suggested but got this error `raise PyperclipException(EXCEPT_MSG) pandas.io.clipboard.PyperclipException: Pyperclip could not find a copy/paste mechanism for your system.` – Mayur Satav Jun 28 '20 at 11:03
  • I don't know your environment, so I cannot say which solution would work, but there are many solutions offered besides the answer I linked in that thread, so you might want to try a few until you find one that works for you – Diziet Asahi Jun 28 '20 at 11:54
  • i think you haven't get my question i want to button `widget` over `matplot` graph window so that `onClick` it will copy the `product id` – Mayur Satav Jun 28 '20 at 12:13