2015-07-30 13 views
18

Sono bloccato con un (si spera) semplice problema. Il mio obiettivo è tracciare una linea tratteggiata interrotta con i dati (non solo il testo).Tracciare la linea tratteggiata interrotta con i dati (simile alla trama del profilo)

Example of how I would imagine a possible result

Come ho scoperto solo per creare una linea tratteggiata tramite linestyle = 'tratteggiata', ogni aiuto è apprezzato per mettere i dati tra i trattini.

Qualcosa di simile, per quanto riguarda l'etichettatura, è già esistente con Matplotlib - come ho visto in the contour line demo.

Matplotlib Contour Demo

Aggiornamento:

Il question link mentioned by Richard in comments è stato molto utile, ma non il 100% come ho detto via commento. Attualmente, lo faccio in questo modo:

line_string2 = '-10 ' + u"\u00b0" +"C" 
l, = ax1.plot(T_m10_X_Values,T_m10_Y_Values) 
pos = [(T_m10_X_Values[-2]+T_m10_X_Values[-1])/2., (T_m10_Y_Values[-2]+T_m10_Y_Values[-1])/2.] 
# transform data points to screen space 
xscreen = ax1.transData.transform(zip(T_m10_Y_Values[-2::],T_m10_Y_Values[-2::])) 
rot = np.rad2deg(np.arctan2(*np.abs(np.gradient(xscreen)[0][0][::-1]))) 
ltex = plt.text(pos[0], pos[1], line_string2, size=9, rotation=rot, color='b',ha="center", va="bottom",bbox = dict(ec='1',fc='1', alpha=0.5)) 

Qui potete vedere una fotografia istantanea del risultato. Il meno 20 ° C è senza BBox.

enter image description here

+1

Ciao - Ho modificato le immagini alla domanda. Potresti modificare un [Esempio MInimico, Completo e Verificabile] (http://stackoverflow.com/help/mcve), ad esempio il codice che stai utilizzando per tracciare le tue linee e i dati che desideri inserire tra un trattino e l'altro? Quindi potremmo essere in grado di aiutare - non penso che esista una semplice soluzione "one-size-fits-all" come "usa lo style = dashes_with_labels" o altro. –

+1

In realtà, potresti voler dare un'occhiata a questa domanda e rispondere a http://stackoverflow.com/questions/19876882/print-string-over-plotted-line-mimic-contour-plot-labels. Potrebbe essere sufficiente. Se questo non è - e non puoi adattarli per ottenere il ripetuto che desideri - aggiungi un riferimento a questi nella tua domanda (per mostrare che sei consapevole) e specifica che l'etichetta ripetuta è importante per te. –

+0

Ciao a tutti, quello citato link da Richard era l'occhio di bue, almeno sembrava così. Il risultato è esattamente ciò di cui ho bisogno. Ma ho una griglia dietro visualizzata tramite imshow e non sfondo bianco. Si può vedere che la linea tratteggiata con il testo è il risultato di un bbox, che sovrascrive la linea. Anche lavorare con zorder non ha funzionato. Ma con questa soluzione finora posso vivere. Se non c'è altro modo. – Matthias

risposta

1

risposta rapida e sporca con annotate:

import matplotlib.pyplot as plt 
import numpy as np 

x = list(reversed([1.81,1.715,1.78,1.613,1.629,1.714,1.62,1.738,1.495,1.669,1.57,1.877,1.385])) 
y = [0.924,0.915,0.914,0.91,0.909,0.905,0.905,0.893,0.886,0.881,0.873,0.873,0.844] 

def plot_with_text(x, y, text, text_count=None): 
    text_count = (2 * (len(x)/len(text))) if text_count is None else text_count 
    fig, ax = plt.subplots(1,1) 
    l, = ax.plot(x,y) 
    text_size = len(text) * 10 
    idx_step = len(x)/text_count 
    for idx_num in range(text_count): 
     idx = int(idx_num * idx_step) 
     text_pos = [x[idx], y[idx]] 
     xscreen = ax.transData.transform(zip(x[max(0, idx-1):min(len(x), idx+2)], y[max(0, idx-1):min(len(y), idx+2)])) 
     a = np.abs(np.gradient(xscreen)[0][0]) 
     rot = np.rad2deg(np.arctan2(*a)) - 90 
     ax.annotate(text, xy=text_pos, color="r", bbox=dict(ec="1", fc="1", alpha=0.9), rotation=rot, ha="center", va="center") 

plot_with_text(x, y, "test") 

rendimenti:

plot

Si può giocare con gli offset per risultati più soddisfacenti.

Problemi correlati