2016-12-11 3 views
10

R Riverplot(v0.5)でSankeyダイアグラムを作成しましたが、出力はRStudioでは小さく見えますが、エクスポートまたはズームインすると色が暗くなりますアウトラインまたはグリッド線。R - 出力プロットのグリッドラインまたはアウトラインで囲まれたRiverplotパッケージ

The Riverplot image linked here shows the problem

私は、形状の輪郭が、私が塗りに使用する透明性を一致していないので、それがかもしれないと思いますか?

アウトラインを完全に取り除く方法(半透明にするのではなく)を見つける必要があるかもしれません。なぜなら、ゼロの値を持つフローが細い線として表示される理由もあると思います。

#loading packages 
library(readr) 
library("riverplot", lib.loc="C:/Program Files/R/R-3.3.2/library") 
library(RColorBrewer) 

#loaing data 
Cambs_flows <- read_csv("~/RProjects/Cambs_flows4.csv") 

#defining the edges 
edges = rep(Cambs_flows, col.names = c("N1","N2","Value")) 
edges <- data.frame(edges) 
edges$ID <- 1:25 

#defining the nodes 
nodes <- data.frame(ID = c("Cambridge","S Cambs","Rest of E","Rest of UK","Abroad","to Cambridge","to S Cambs","to Rest of E","to Rest of UK","to Abroad")) 
nodes$x = c(1,1,1,1,1,2,2,2,2,2) 
nodes$y = c(1,2,3,4,5,1,2,3,4,5) 

#picking colours 
palette = paste0(brewer.pal(5, "Set1"), "90") 

#plot styles 
styles = lapply(nodes$y, function(n) { 
    list(col = palette[n], lty = 0, textcol = "black") 
}) 

#matching nodes to names 
names(styles) = nodes$ID 

#defining the river 
r <- makeRiver(nodes, edges, 
       node_labels = c("Cambridge","S Cambs","Rest of E","Rest of UK","Abroad","to Cambridge","to S Cambs","to Rest of E","to Rest of UK","to Abroad"), 
       node_styles = styles) 

#Plotting 
plot(r, plot_area = 0.9) 

そして、私のデータはここ

dput(Cambs_flows) 
structure(list(N1 = c("Cambridge", "Cambridge", "Cambridge", 
"Cambridge", "Cambridge", "S Cambs", "S Cambs", "S Cambs", "S Cambs", 
"S Cambs", "Rest of E", "Rest of E", "Rest of E", "Rest of E", 
"Rest of E", "Rest of UK", "Rest of UK", "Rest of UK", "Rest of UK", 
"Rest of UK", "Abroad", "Abroad", "Abroad", "Abroad", "Abroad" 
), N2 = c("to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK", 
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK", 
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK", 
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK", 
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK", 
"to Abroad"), Value = c(0L, 1616L, 2779L, 13500L, 5670L, 2593L, 
0L, 2975L, 4742L, 1641L, 2555L, 3433L, 0L, 0L, 0L, 6981L, 3802L, 
0L, 0L, 0L, 5670L, 1641L, 0L, 0L, 0L)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -25L), .Names = c("N1", "N2", 
"Value"), spec = structure(list(cols = structure(list(N1 = structure(list(), class = c("collector_character", 
"collector")), N2 = structure(list(), class = c("collector_character", 
"collector")), Value = structure(list(), class = c("collector_integer", 
"collector"))), .Names = c("N1", "N2", "Value")), default = structure(list(), class = c("collector_guess", 
"collector"))), .Names = c("cols", "default"), class = "col_spec")) 
+0

これを解決できましたか? – radek

+1

いいえ奇妙なことに、2回実行すると、プロットが正常に見える2回目ですが、エクスポートしてそのラインが戻ってきます。私はちょうど理想的ではないスクリーングラブを行っています。 – String

+0

OK。おそらく小さな賞金が注目を集めるのに役立つでしょうか? – radek

答えて

13

犯人はriverplot::curvesegの行です:

私のコードはここにあります。この機能をハックして修正するか、機能をハッキングする必要のない非常に簡単な回避策があります。実際、単純な解決策はおそらく多くの場合可能ですが、最初に関数をハックする方法を説明するので、回避策も機能する理由を理解しています。

がUPDATE:あなただけのシンプルなソリューションをしたい場合は、この答えの最後までスクロール変更は以下になりましたriverplotバージョンで実装されていることを提案すると、0.6

機能を編集するには、使用することができます

trace(curveseg, edit=T) 

その後

polygon(c(xx[i], xx[i + 1], xx[i + 1], xx[i]), c(yy[i], 
     yy[i + 1], yy[i + 1] + w, yy[i] + w), col = grad[i], 
     border = grad[i]) 

私たちはここに目を見ることができるの読み込み機能の終わり近くにラインを見つけますパッケージ作成者はパラメータをpolygonに渡さないようにしました(UPDATE:パッケージ作成者がこのようにした理由については、this answerを参照してください)。この行にlty = 0(または、好きな場合はborder = NA)を追加して変更し、OPの場合のように動作します。 (しかし、あなたはPDFファイルをレンダリングしたい場合、これはうまく動作しない場合がありますのでご注意 - here参照)側の注意点として

polygon(c(xx[i], xx[i + 1], xx[i + 1], xx[i]), c(yy[i], 
     yy[i + 1], yy[i + 1] + w, yy[i] + w), col = grad[i], 
     border = grad[i], lty=0) 

enter image description here

を、これもというコメントで、やや奇妙な報告の動作を説明します"それを2回実行すると、2回目のプロットは正常に見えますが、それをエクスポートして戻っても" "と表示されます。 polygonへの呼び出しでltyが指定されていない場合、そのデフォルト値はlty = par("lty")です。当初、デフォルトのpar("lty")は実線ですが、riverplot関数を1回実行した後、riverplot:::draw.nodesの呼び出し中にpar("lty")が0に設定され、riverplotが2回実行されたときに行が表示されなくなりました。しかし、イメージをエクスポートしようとすると、新しいデバイスを開くとpar("lty")がデフォルト値にリセットされます。

この編集で機能を更新する別の方法は、assignInNamespaceを使用してパッケージ機能を独自のバージョンで上書きすることです。機能への変更を必要としないシンプルなソリューションのための今

curveseg.new = function (x0, x1, y0, y1, width = 1, nsteps = 50, col = "#ffcc0066", 
      grad = NULL, lty = 1, form = c("sin", "line")) 
{ 
    w <- width 
    if (!is.null(grad)) { 
    grad <- colorRampPaletteAlpha(grad)(nsteps) 
    } 
    else { 
    grad <- rep(col, nsteps) 
    } 
    form <- match.arg(form, c("sin", "line")) 
    if (form == "sin") { 
    xx <- seq(-pi/2, pi/2, length.out = nsteps) 
    yy <- y0 + (y1 - y0) * (sin(xx) + 1)/2 
    xx <- seq(x0, x1, length.out = nsteps) 
    } 
    if (form == "line") { 
    xx <- seq(x0, x1, length.out = nsteps) 
    yy <- seq(y0, y1, length.out = nsteps) 
    } 
    for (i in 1:(nsteps - 1)) { 
    polygon(c(xx[i], xx[i + 1], xx[i + 1], xx[i]), 
      c(yy[i], yy[i + 1], yy[i + 1] + w, yy[i] + w), 
      col = grad[i], border = grad[i], lty=0) 
    lines(c(xx[i], xx[i + 1]), c(yy[i], yy[i + 1]), lty = lty) 
    lines(c(xx[i], xx[i + 1]), c(yy[i] + w, yy[i + 1] + w), lty = lty) 
    } 
} 

assignInNamespace('curveseg', curveseg.new, 'riverplot', pos = -1, envir = as.environment(pos)) 

:このような

ちょうどあなたプロットする前に行par(lty=0)を追加!

+0

その変更を完了しました! – thc

+1

残念ながら、それは実際にriverplotの元のコードでした(パッケージソースでは引き続きコメントアウトされた行を見ることができます)。しかし、生成されたPDFは、その間に細い白い線があります。理由は分かりませんが、グラフィックがひどく見えます。私は別の答えでこの問題を説明しました。 – January

+1

また、ltyパラメータは "polygon"に直接渡すべきではありません。これはセグメントだけでなく*カーブ全体を囲む*ために使用されるためです。そのため、元のコードでlty = 0となっています。したがって、上記の代替コードは間違っています。 – January

9

ここにパッケージの作者があります。私は現在、パッケージの次のバージョンに含まれる満足のいく解決策を求めて苦労しています。

問題は、RがPDFをビットマップと比較してどのようにレンダリングするかにあります。パッケージの元のバージョンでは、実際にlty = 0をpolygon()に渡しました(コメント付きのソースコードではまだそれを見ることができます)。しかし、ポリゴンの枠線がない場合は、pngグラフィックス上でしか見えません。 pdf出力では、ポリゴンの間に細い白線が表示されます。見てください:

cc <- "#E41A1C90" 
plot.new() 
rect(0.2, 0.2, 0.4, 0.4, col=cc, border=NA) 
rect(0.4, 0.2, 0.6, 0.4, col=cc, border=NA) 
dev.copy2pdf(file="riverplot.pdf") 

Xまたはpngの出力は正しいです。しかし、PDFとしてレンダリングする場合は、recangles間の細い白い線が表示されます:あなたは上記のようなPDFとしてriverplotグラフィックをレンダリングするとき

enter image description here

を、これは本当に悪いになります

enter image description here

私は境界を強制的に追加しましたが、透明性のチェックは忘れました。透明度が使用されていない場合は、このように見えます。境界線はポリゴンと重なるだけでなく、互いに見えますが、見えません。これでPDFが受け入れられるようになりました。しかし、あなたが透明性を持っているならば、それは数字を駄目にします。

EDIT

私は今、CRANにriverplotのバージョン0.6をアップロードしています。既存の図面のどの部分にもriverplotを追加できるようになりました。デフォルトでは、lty = 0が再び使用されます。しかし、今度は "fix.pdf"というオプションがあります。このオプションは、セグメントの周りに再び枠線を描画するためにTRUEに設定することができます。

ボトムライン、そして今のソリューション:

  1. 使用は、あなたがPDFをレンダリングしたい場合は、透明性を使用していないとあなた場合
  2. TRUE fix.pdf =を使用0.6`
  3. をriverplot透明性とPDFの両方を使用したい場合は、問題の解決にお役立てください。
+1

1月号パッケージのアップデートに感謝します!奨励金をいただきました。私は彼の最初のハックのためにdwwと半分に分割したいですが! – radek

+1

ありがとう!私はここに記述されている実際の問題への回答を得るために、賞金+50点を追加しました:http://stackoverflow.com/questions/42387066/color-gradients-in-r-in-pdf-and-bitmap-output – January

関連する問題