2017-11-10 1 views
2

Matplotlib은 플롯의 개별 요소를 래스터 화하고 혼합 된 픽셀/벡터 그래픽 (.pdf)으로 저장합니다 (예 : this answer 참조). ggplot2을 사용하면 어떻게 R에서 동일한 결과를 얻을 수 있습니까? 다음ggplot의 단일 레이어를 래스터 화하는 방법은 무엇입니까?


나는 단지 geom_point 레이어를 래스터 화하고자하는 장난감 문제입니다. .pdf로 저장하면

set.seed(1) 
x <- rlnorm(10000,4) 
y <- 1+rpois(length(x),lambda=x/10+1/x) 
z <- sample(letters[1:2],length(x), replace=TRUE) 

p <- ggplot(data.frame(x,y,z),aes(x=x,y=y)) + 
    facet_wrap("z") + 
    geom_point(size=0.1,alpha=0.1) + 
    scale_x_log10()+scale_y_log10() + 
    geom_smooth(method="gam",formula = y ~ s(x, bs = "cs")) 
print(p) 
ggsave("out.pdf", p) 

은 그대로, 어도비 리더 DC는 그림을 렌더링하기 위해 ~ 1 초를 필요로한다. 당신이 .png 버전을 확인하실 수 있습니다 : 물론 out.png

를, 원시 데이터

+0

실제 문제 일 수 있습니다. 과학 기사의 두 가지 버전을 고려하십시오. https://arxiv.org/abs/1501.01332v2 (모든 그림 벡터) v https://arxiv.org/abs/1501.01332v3 (모든 수치는 래스터 화 됨). 첫 번째 파일은 프린터 또는 pdf 뷰어에 용지가 걸릴 수 있으며 두 번째 파일은 훨씬 더 큰 파일 크기를 갖는 반면 선명하지는 않습니다. –

+1

https://stackoverflow.com/a/42059772 – baptiste

+3

해결 방법으로 전체 플롯을'dpi = 600' 또는'dpi = 1200'으로 png로 저장하면 거대한 파일을 생성하지 않고 비교적 선명한 래스터 이미지를 제공해야합니다. PNG는 라인 그래픽 용으로 특별히 설계되었습니다. –

답변

3

난 당신이 대답이 질문을하지 자신을 설정 한 생각을하려하지 않음으로써 문제를 방지하는 것이 가능하다. 당신은 쓰기 :

내가 대답, 즉 geom_... 명령에 대한 래퍼로서 이들거나 추가 매개 변수로, 기존의 플로팅 명령에 대한 최소한의 변경 래스터 레이어 플롯을 내보낼 수 있습니다 ggplot2의 확장을 제공 할 것으로 예상 ggsave 명령은 연결된 질문에서 제공되는 해로운 해결 방법이 아니라 플롯 명령의 평가되지 않은 부분 (매초마다 래스터 화됨) 목록을 필요로합니다.

이것은 고도로 숙련 된 개발자가 수 주일 이상 노력을 쉽게 요구할 수있는 주요 개발 노력입니다. 스택 오버플로 (Stack Overflow) 문제로 인해 아무도이를 수행하지 않을 것입니다. 기능적으로 구현하는 대신에, 당신이 요구하는 것을 구현할 수있는 방법과 그것이 왜 어려운지를 설명 할 것입니다.

선수

은의 우리가 처리됩니다 핵심 선수로 시작하자. 최상위 레벨에서는 ggplot2 라이브러리가 있습니다. 데이터 프레임을 가져 와서 그림으로 변환합니다. ggplot2 그 자체는 저수준 도면에 대해서는 아무 것도 모른다. 그래픽 오브젝트 (grobs) 형식으로 grid 라이브러리에 전달되는 선, 다각형, 텍스트 등 만 처리합니다.

grid 라이브러리 자체는 상당히 높은 수준의 라이브러리입니다. 또한 하위 수준 그리기에 대해 많이 알지 못합니다. R 그래픽 장치로 전달되는 선, 다각형, 텍스트 등을 주로 처리합니다. 장치가 실제 그리기를 수행합니다.

다양한 R 그래픽 장치가 있습니다. R 명령 행에 ?Devices을 입력하면 불완전한 목록을 볼 수 있습니다. 벡터 그래픽 장치가있다 등 pdf, postscript, 또는 svg 등, 래스터 장치 등 png, jpeg, 또는 tiff, 대화 형 장치와 같은 X11 또는 quartz있다. 분명히 래스터 화는 벡터 그래픽 장치에만 의미가 있습니다. 래스터 장치가 모든 것을 래스터 화하기 때문입니다. 중요한 점은 ggplot2도 아니고 grid도 현재 사용중인 그래픽 장치를 알고 있거나 신경 쓰지 않는 것입니다. 그들은 모든 장치에서 그릴 수있는 그래픽 객체를 처리합니다.

이상적인 고레벨 인터페이스

고레벨 인터페이스 ggplot2layer() 함수 옵션 rasterize 구성한다. 이러한 방식으로, 포인트 층을 래스터 화하기 위해 간단히 예를 들어 geom_point(rasterize = TRUE)을 쓸 수있다. 이것들은 모두 layer()을 호출하기 때문에 모든 기하 구조와 통계에 대해 투명하게 작동합니다.

가능한 구현

나는 대부분의 불가능의 이상에 주문 구현의 네 가지 경로를 참조하십시오.

1. 이상적으로, layer() 기능은 단순히 음모의 일부가 래스터 할 그것을 말할 수있는 그래픽 장치에 넘겨 것 grid 라이브러리에 rasterize 옵션을 넘겨 것입니다. 이 접근법은 그래픽 장치 API의 주요 변경을 필요로합니다. 나는 이런 일이 일어나지 않는 것을 본다. 내 평생은 아니지.

2. 그래픽 장치에서 grob를 그릴 때 임의의 grob를 필요에 따라 래스터화할 수있는 새로운 grob 유형을 작성할 수 있습니다. 이 접근 방식은 그래픽 장치 API의 변경을 필요로하지 않지만 grid 라이브러리의 저수준 구현에 대한 자세한 지식이 필요합니다. 또한 그러한 수치를 대화식으로 보는 것이 매우 느릴 수도 있습니다.

3. 약간 단순한 2.의 대안은 grob 구조에서 임의 grob를 한 번만 래스터 화 한 다음 해당 grob를 그릴 때마다 다시 사용하는 것입니다. 인터랙티브 그래픽 장치에서는 상당히 빨라지지만 대화식으로 종횡비가 변경되면 그림이 왜곡됩니다. 그럼에도 불구하고,이 기능의 주요 용도는 pdf 출력을 생성하는 것이므로 (이 경우)이 옵션으로 충분할 수 있습니다.

4. 마지막으로 래스터 화는 layer() 함수에서도 발생할 수 있으며이 함수는 일반 래스터 grob를 grob 트리에 넣을 수 있습니다. 그 해결책은 기술 described here.과 비슷합니다. 기술적으로는 3과 크게 다르지 않습니다. 어느 경우 든 grob 트리를 래스터 화 한 다음 래스터 grob로 바꾸는 코드를 작성해야합니다. GROB 트리의 일부를 래스터

기술 장애물

, 우리는 렌더링 할 수있는 R 래스터 그래픽 장치로 보낼해야 할 것이다. 그러나 메모리로 렌더링하는 것은 없습니다. 따라서 임시 파일 (예 : png() 사용)로 렌더링 한 다음 파일을 다시 읽어야합니다. 그럴 수도 있지만 추한 것입니다. 또한 모든 R 설치에서 사용할 수있는 기능 (예 : png())에 의존합니다.

둘째, grob 트리의 일부를 전체 렌더링과 별도로 렌더링하려면 현재 열려있는 그래픽 장치 외에 새 그래픽 장치를 열어야합니다. 그럴 수도 있지만 예상치 못한 버그가 발생할 수 있습니다. 나는 항상 그러한 버그를 다루고있다. 이 기술을 사용하는 코드와 관련된 문제는 here 또는 here입니다. 래스터 화 기능을 구현하는 사람은 누구나 그러한 문제를 처리해야합니다.

마지막으로 함수를 대체해야하므로 래스터 화 코드를 ggplot2 라이브러리로 가져와야합니다. 별도의 패키지에서이를 수행 할 방법이 없다고 생각합니다. 래스터 화 솔루션이 얼마나 까다로운지를 감안할 때 (이전 두 단락 참조), 이는 어려운 명령 일 수 있습니다.

+0

훌륭한 분석! 다행히도 그것은 s.b.에 대한 동기 부여입니다. 내 질문보다 솔루션을 구현하는 방법! '그래픽 장치 API '문서를 어디서 찾을 수 있는지 알고 있습니까? 네가 말했을 때 "내 평생 아니야, 적어도." 당신은 실제로 "R 코어 팀의 일생 중에"말하지 않았습니까? 아니면이 비관적 인 진술의 이유는 무엇입니까? –

+0

그래픽 장치의 API를 변경하는 것은 모든 장치 드라이버와 모든 클라이언트 코드를 변경해야하는 주요 작업입니다. 그것은 쉽게 일어나지 않을 것입니다. 이미 그라디언트 채우기, 패턴 채우기, 이미지 채우기 등과 같이 많은 중요한 것들이 빠져 있습니다. 래스터 라이 제이션은 우선 순위가 너무 높습니다. 응답은 다음과 같습니다. 더 높은 수준에서 래스터 화 한 다음 래스터 화 된 이미지를 그래픽 장치로 전달합니다. 그리고 그것은 완전히 불합리하지 않습니다. –

+0

# 2 접근법은 아마도 가장 일반적이며 가장 실현 가능성이 있다고 생각합니다. 대부분 'rastergrob'의 코드를 복사하고 [drawDetails' 함수를 다시 구현하는 것이 관련되어 있다고 생각합니다 (https://github.com/wch/r-source/blob/trunk/src/library/grid/R/primitives). .R # L1222), 즉석에서 grob를 래스터 화 한 다음 래스터 화 된 이미지를 저수준 그래픽 장치로 보냅니다. @baptiste는 나보다이 사실을 더 잘 이해하고 있으며, 내가 모르는 몇 가지 함정을 보게 될 것입니다. –

관련 문제