Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to make bullet Picture by Python

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail how to make bullet pictures in Python. The editor thinks it is very practical, so I share it with you as a reference. I hope you can get something after reading this article.

1. What is a bullet map

A conventional definition of a bullet diagram:

The bullet map uses length / height, position, and color to encode the data to show the actual situation compared to the target and performance belt

Let's first take a look at what the bullet picture looks like:

Bullet maps have a single major metric (for example, revenue from the current year to date), which is compared with one or more other metrics to enrich its meaning (for example, compared to goals). And display it in the context of the qualitative scope of performance, such as poor, satisfactory, and good. The qualitative range is displayed as different intensities of a single tone, allowing color-blind people to identify them and limiting the use of colors on the dashboard to a minimum.

All right, almost this is the application scene and drawing standard of the bullet diagram, so let's start making it.

2. Build the chart

The idea is that you can use a stacked bar chart to represent various ranges, and another smaller bar chart to represent values, and finally, mark the target with a vertical line.

As you can see, we need multiple component layers, and it is more convenient to use matplotlib to implement it.

Import matplotlib.pyplot as pltimport seaborn as snsfrom matplotlib.ticker import FuncFormatter%matplotlib inline

We also imported Seaborn here because Seaborn has some very useful tools to manage palettes, which is easier to use than to try to copy it in other ways

The main reason we need to generate color palettes is that we probably want to generate visually attractive color schemes for various qualitative ranges, which is much more convenient to do directly with seaborn.

In the following example, we can use the palplot convenience function to display a palette of five green tones

Sns.palplot (sns.light_palette ("green", 5))

Sns.palplot (sns.light_palette ("purple", 8, reverse=True))

Make eight different shades of purple in reverse order

Now that we know how to set up the color palette, let's use Matplotlib to create a simple bullet diagram based on the principles listed above

First, define the values we want to draw

Limits = [80,100,150] data_to_plot = ("Example 1", 105,120)

This creates three ranges: 0-80, 81-100, 101-150, and a "sample" line with a value of 105 and a target line of 120. Next, build a blue palette:

Palette = sns.color_palette ("Blues_r", len (limits))

Next is the stacked bar chart of the build scope:

Fig, ax = plt.subplots () ax.set_aspect ('equal') ax.set_yticks ([1]) ax.set_yticklabels ([data_to_plot [0]]) prev_limit = 0for idx, lim in enumerate (limits): ax.barh ([1], lim-prev_limit, left=prev_limit, height=15, color=palette [idx]) prev_limit = lim

Then we can add a smaller bar chart to represent the value of 105:

Ax.barh ([1], data_to_plot [1], color='black', height=5)

It is beginning to take shape.

The final step is to add the target tag using axvline:

Ax.axvline (data_to_plot [2], color= "gray", ymin=0.10, ymax=0.9)

Above I have completed the simple production of the bullet diagram, but all of our test values are written dead, so let's write a code that can fill in any value.

3. Final code

Def bulletgraph (data=None, limits=None, labels=None, axis_label=None, title=None, size= (5,3), palette=None, formatter=None, target_color= "gray", bar_color= "black", label_color= "gray"): # Determine the max value for adjusting the bar height # Dividing by 10 seems to work pretty well h = limits [- 1] / 10 # Use the green palette as a sensible default if palette is None: palette= sns.light_palette ("green") Len (limits), reverse=False) # Must be able to handle one or many data sets via multiple subplots if len (data) = = 1: fig, ax = plt.subplots (figsize=size, sharex=True) else: fig, axarr = plt.subplots (len (data), figsize=size, sharex=True) # Add each bullet graph bar to a subplot for idx Item in enumerate (data): # Get the axis from the array of axes returned when the plot is created if len (data) > 1: ax = axarr [idx] # Formatting to get rid of extra marking clutter ax.set_aspect ('equal') ax.set_yticklabels ([item [0]]) ax.set_yticks ([1]) ax.spines [' bottom']. Set _ visible (False) ax.spines ['top']. Set_visible (False) ax.spines [' right']. Set_visible (False) ax.spines ['left'] .set_visible (False) prev_limit = 0 for idx2 Lim in enumerate (limits): # Draw the bar ax.barh ([1], lim-prev_limit, left=prev_limit, height=h, color=palette [idx2]) prev_limit = lim rects = ax.patches # The last item in the list is the value we're measuring # Draw the value we're measuring ax.barh ([1], item [1], height= (h / 3)) Color=bar_color) # Need the ymin and max in order to make sure the target marker # fits ymin, ymax = ax.get_ylim () ax.vlines (item [2], ymin * .9, ymax * .9, linewidth=1.5, color=target_color) # Now make some labels if labels is not None: for rect, label in zip (rects Labels): height = rect.get_height () ax.text (rect.get_x () + rect.get_width () / 2,-height * .4, label, ha='center', va='bottom' Color=label_color) if formatter: ax.xaxis.set_major_formatter (formatter) if axis_label: ax.set_xlabel (axis_label) if title: fig.suptitle (title, fontsize=14) fig.subplots_adjust (hspace=0)

Although the code looks a little long, it is actually the superposition of the above steps, which is relatively simple, so I won't repeat it.

Let's call it directly to see the effect:

Data_to_plot2 = [(Zhang San, 105,120), (Li Si, 99,110), (Wang Wu, 109,125), (Zhao Liu, 135,123), (Qian Qi, 45,105)] bulletgraph (data_to_plot2, limits= [20,60,100,160], labels= ["Poor") "OK", "Good", "Excellent"], size= (8 Performance Measure 5), axis_label= "Performance Measure", label_color= "black", bar_color= "# 252525", target_color='#f7f7f7', title= "sales Representative performance")

We can also make some optimizations to format the x-axis to display information more consistently

In the following example, we can measure the marketing budget performance of a hypothetical company

Def money (x, pos): 'The two args are the value and tick position' return "${:, .0f}" .format (x) money_fmt = FuncFormatter (money) data_to_plot3 = [("HR", 50000, 60000), ("Marketing", 75000, 65000), ("Sales", 125000, 80000), ("rattled", 195000) 115000)] palette= sns.light_palette ("grey", 3, reverse=False) bulletgraph (data_to_plot3, limits= [50000, 125000, 200000], labels= ["Below", "On Target", "Above"], size= (102.5), axis_label= "Annual Budget", label_color= "black", bar_color= "# 252525", target_color='#f7f7f7', palette=palette, title= "Marketing Channel Budget performance" Formatter=money_fmt)

This is the end of the article on "how to make bullet pictures in Python". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report