我想用一些案文的图表来说明这些条码,但如果这些条条码相互接近并具有可比的高度,则该说明在外加,因此难以读(说明的坐标来自条形位置和高度)。
如果发生碰撞,是否有办法改变其中之一?
<><>Edit>: 酒吧非常薄弱,有时非常接近,只是为了纵向地解决问题。
A picture might clarify things:
我想用一些案文的图表来说明这些条码,但如果这些条条码相互接近并具有可比的高度,则该说明在外加,因此难以读(说明的坐标来自条形位置和高度)。
如果发生碰撞,是否有办法改变其中之一?
<><>Edit>: 酒吧非常薄弱,有时非常接近,只是为了纵向地解决问题。
A picture might clarify things:
I ve written a quick solution, which checks each annotation position against default bounding boxes for all the other annotations. If there is a collision it changes its position to the next available collision free place. It also puts in nice arrows.
For a fairly extreme example, it will produce this (none of the numbers overlap):
Instead of this:
该守则是:
import numpy as np
import matplotlib.pyplot as plt
from numpy.random import *
def get_text_positions(x_data, y_data, txt_width, txt_height):
a = zip(y_data, x_data)
text_positions = y_data.copy()
for index, (y, x) in enumerate(a):
local_text_positions = [i for i in a if i[0] > (y - txt_height)
and (abs(i[1] - x) < txt_width * 2) and i != (y,x)]
if local_text_positions:
sorted_ltp = sorted(local_text_positions)
if abs(sorted_ltp[0][0] - y) < txt_height: #True == collision
differ = np.diff(sorted_ltp, axis=0)
a[index] = (sorted_ltp[-1][0] + txt_height, a[index][1])
text_positions[index] = sorted_ltp[-1][0] + txt_height
for k, (j, m) in enumerate(differ):
#j is the vertical distance between words
if j > txt_height * 2: #if True then room to fit a word in
a[index] = (sorted_ltp[k][0] + txt_height, a[index][1])
text_positions[index] = sorted_ltp[k][0] + txt_height
break
return text_positions
def text_plotter(x_data, y_data, text_positions, axis,txt_width,txt_height):
for x,y,t in zip(x_data, y_data, text_positions):
axis.text(x - txt_width, 1.01*t, %d %int(y),rotation=0, color= blue )
if y != t:
axis.arrow(x, t,0,y-t, color= red ,alpha=0.3, width=txt_width*0.1,
head_width=txt_width, head_length=txt_height*0.5,
zorder=0,length_includes_head=True)
这里是生产这些土地的法典,显示使用:
#random test data:
x_data = random_sample(100)
y_data = random_integers(10,50,(100))
#GOOD PLOT:
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.bar(x_data, y_data,width=0.00001)
#set the bbox for the text. Increase txt_width for wider text.
txt_height = 0.04*(plt.ylim()[1] - plt.ylim()[0])
txt_width = 0.02*(plt.xlim()[1] - plt.xlim()[0])
#Get the corrected text positions, then write the text.
text_positions = get_text_positions(x_data, y_data, txt_width, txt_height)
text_plotter(x_data, y_data, text_positions, ax2, txt_width, txt_height)
plt.ylim(0,max(text_positions)+2*txt_height)
plt.xlim(-0.1,1.1)
#BAD PLOT:
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(x_data, y_data, width=0.0001)
#write the text:
for x,y in zip(x_data, y_data):
ax.text(x - txt_width, 1.01*y, %d %int(y),rotation=0)
plt.ylim(0,max(text_positions)+2*txt_height)
plt.xlim(-0.1,1.1)
plt.show()
Another option using my library adjustText
, written specially for this purpose (https://github.com/Phlya/adjustText). I think it s probably significantly slower that the accepted answer (it slows down considerably with a lot of bars), but much more general and configurable.
from adjustText import adjust_text
np.random.seed(2017)
x_data = np.random.random_sample(100)
y_data = np.random.random_integers(10,50,(100))
f, ax = plt.subplots(dpi=300)
bars = ax.bar(x_data, y_data, width=0.001, facecolor= k )
texts = []
for x, y in zip(x_data, y_data):
texts.append(plt.text(x, y, y, horizontalalignment= center , color= b ))
adjust_text(texts, add_objects=bars, autoalign= y , expand_objects=(0.1, 1),
only_move={ points : , text : y , objects : y }, force_text=0.75, force_objects=0.1,
arrowprops=dict(arrowstyle="simple, head_width=0.25, tail_width=0.05", color= r , lw=0.5, alpha=0.5))
plt.show()
如果我们允许在X轴线上进行自动调整,就会变得更好(我刚刚需要解决一个小问题,即它像把标签放在点上,而不是放在一边......)。
np.random.seed(2017)
x_data = np.random.random_sample(100)
y_data = np.random.random_integers(10,50,(100))
f, ax = plt.subplots(dpi=300)
bars = ax.bar(x_data, y_data, width=0.001, facecolor= k )
texts = []
for x, y in zip(x_data, y_data):
texts.append(plt.text(x, y, y, horizontalalignment= center , size=7, color= b ))
adjust_text(texts, add_objects=bars, autoalign= xy , expand_objects=(0.1, 1),
only_move={ points : , text : y , objects : y }, force_text=0.75, force_objects=0.1,
arrowprops=dict(arrowstyle="simple, head_width=0.25, tail_width=0.05", color= r , lw=0.5, alpha=0.5))
plt.show()
(我当然必须在此调整一些参数)
一种选择是轮换案文/说明,由<代码>rotation关键词/property确定。 在以下例子中,我轮换了90度案文,以保障文本与邻近文本取得一致。 我也确定了<代码>va(verticalalignment
)关键词,以便案文放在条码上(在我用来界定案文的意思之前):
import matplotlib.pyplot as plt
data = [10, 8, 8, 5]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(range(4),data)
ax.set_ylim(0,12)
# extra .4 is because it s half the default width (.8):
ax.text(1.4,8,"2nd bar",rotation=90,va= bottom )
ax.text(2.4,8,"3nd bar",rotation=90,va= bottom )
plt.show()
The result is the following figure:
如果不同说明之间发生碰撞,则从方案上加以确定,是一个更深入的过程。 这个问题可能值得单独讨论:。 Matplotlib text dimensions。
Just thought I would provide an alternative solution that I just created textalloc that makes sure that text-boxes avoids overlap with both each other and lines when possible, and is fast.
举例来说,你可以这样作:
import textalloc as ta
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(2017)
x_data = np.random.random_sample(100)
y_data = np.random.random_integers(10,50,(100))
f, ax = plt.subplots(dpi=200)
bars = ax.bar(x_data, y_data, width=0.002, facecolor= k )
ta.allocate_text(f,ax,x_data,y_data,
[str(yy) for yy in list(y_data)],
x_lines=[np.array([xx,xx]) for xx in list(x_data)],
y_lines=[np.array([0,yy]) for yy in list(y_data)],
textsize=8,
margin=0.004,
min_distance=0.005,
linewidth=0.7,
textcolor="b")
plt.show()
Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...
I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...
Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...
Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...
I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...
Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...
Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...
I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...